Django- ORM操作

一 、查询

1、一对多

实例一(正向,用字段):

# 查询红楼梦的出版社名称
#方式1:
ret=Book.objects.filter(title="红楼梦").values("publish__name")           
print(ret)                                                          
# <QuerySet [{'publish__name': '北京出版社'}]>
# 方式2:
res=Publish.objects.filter(book__title="红楼梦").values("name")          
print(res)                                                          
#<QuerySet [{'name': '北京出版社'}]>

实例二(反向,用表名):

# 查询沙河出版社出版过的书籍名称
#方式1:
ret=Publish.objects.filter(name="沙河出版社").values("book__title")
print(ret)                                                         
#<QuerySet [{'book__title': '金品梅2'}, {'book__title': '金品梅3'}]>
#方式2:
res=Book.objects.filter(publish__name="沙河出版社").values("title")
print(res)                                                         
#<QuerySet [{'title': '金品梅2'}, {'title': '金品梅3'}]>

2、多对多

实例一(正向,用字段):

# 查询红楼梦所有作者的名字
ret=Book.objects.filter(title="红楼梦").values("authors__name")
print(ret)                                                       
#<QuerySet [{'authors__name': 'alex'}, {'authors__name': 'egon'}]>

实例二(反向,用表名):

#查询alex出版过的所有书籍
ret=Author.objects.filter(name="alex").values("book__title")
print(ret)                                                       
#<QuerySet [{'book__title': '金品梅2'}, {'book__title': '红楼梦'}]>

3、一对一

实例一(正向,用字段):

# 查询地址在沙河并且email是123的作者的名字
ret=AuthorDetail.objects.filter(adrr="沙河",email=123).values("author__name")
print(ret)                                                        
#<QuerySet [{'author__name': 'alex'}]>

实例二(反向,用表名):

# 查询alex作者的adrr地址
ret = Author.objects.filter(name="alex").values("authordetail__adrr")
print(ret)                                                      
#<QuerySet [{'authordetail__adrr': '沙河'}]>

实例三(综合实例):

#email以456开头的作者出版过的所有书籍名称以及出版社名称  ret=Book.objects.filter(authors__authordetail__email__startswith="456").values("title","publish__name")
print(ret)

  总结,在上一章的对象查询中,我们可以总结为所有的查询是基于一个models对象,而本节中双下划线查询均是基于queryset对象进行的!反向查询使用的表名同样必须为小写。

二、聚合函数(aggregate)

  aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。如下例:

#查询所有书籍的平均价格
# 实例1:
ret=Book.objects.all().aggregate(Avg("price"))
print(ret)                                                         
#{'price__avg': 172.66666666666666}
# 实例2:
res = Book.objects.all().aggregate(avgPrice=Avg("price"))
print(res)                                                         
#{'avgPrice': 172.66666666666666}

  如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

# 查询所有书籍的平均价格、价格最大值、价格最小值
ret = Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price"))
print(ret)                         
#{'price__avg': 172.66666666666666, 'price__min': Decimal('123.00'), 'price__max': Decimal('230.00')}

  以上实例中需要按照如下方式引入相应的模块方法: ``from django.db.models ``import Avg, ``Max``, ``Min

三、分组函数(annotate)

  annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

  实例1:查询每一个出版社出版过的书籍个数

ret=Publish.objects.all().annotate(num=Count("book__title"))     #可以理解为每一个出版社对象增加一个num字段,该字段值是通过聚合函数联表求得
for pub_obj  in ret:
    print(pub_obj.name,pub_obj.num)

 annotate的返回值是querySet,如果不想遍历对象,可以用上values_list,如下:

ret = Publish.objects.all().annotate(num=Count("book__title")).values_list("name","num")
print(ret)                                                       
#<QuerySet [('人民出版社', 0), ('沙河出版社', 2), ('北京出版社', 1)]>

  实例2:查询每一本书的作者个数

ret=Book.objects.all().annotate(counts=Count("authors__nid")).values("title","counts")
print(ret)        
#<QuerySet [{'title': '金品梅2', 'counts': 2}, {'title': '金品梅3', 'counts': 2}, {'title': '红楼梦', 'counts': 2}]>

二、方法

python生成requirements.txt项目依赖环境

进入python 项目目录下,执行命令

pip freeze > requirements.txt

生成的requirements.txt 里面就记录了当前所有已经安装的依赖包以及版本号

然后将生成的requirements.txt 拷贝到需要安装同样依赖环境的服务器上

最后执行命令

pip install -r requirements.txt

就可以将所有依赖一次安装完成

django中所有的命令

下载django

pip install django==1.11.25 -i 源

创建django项目

django-admin startproject 项目名

启动项目

切换到项目目录下

python manage.py runserver # 127.0.0.1:8000

python manage.py runserver 80 # 127.0.0.1:80

python manage.py runserver 0.0.0.0::80 # 0.0.0.0::80

创建app

python manage.py startapp app名称

数据库迁移的命令

python manage.py makemigrations # 检测已经注册app下的models变更记录

python manage.py migrate # 将变更记录同步到数据库中

request

request.POST    #  POST提交的数据 {}    urlencode编码
request.GET     #   url上携带的参数  ?id=1  {id:1}
request.method  #  请求方法  GET POST
request.path_info  # 路径信息  不包含IP和端口 也不包含查询参数
request.FILES   # 上传的文件 enctype='form-data'
request.session  # {}  session 
request.COOKIES  # cookie  
request.META   # 请求头的信息  HTTP_  小写——》  大写  - ——》 _
request.body  # 请求体  原始数据

request.get_full_path()  #  完整的路径信息 不包含IP和端口 包含查询参数
request.is_ajax()  # 是否是ajax请求
request.get_signed_cookie(key,salt,defalut='')

response

HttpResponse('字符串')   #  字符串
JsonResponse({})   JsonResponse([],safe=False) 
render(request,'模板文件的路径',{})   # 返回页面 已经替换好了
redirect('地址或者URLname')   # 重定向  响应头Location:地址 301 302 
TemplateResponse(request,'模板文件的路径',{})  # 后续在调用render方式进行渲染

ORM

正向查询

有关联关系的哪一方成为正向--也就是多的哪一方 -- 属性查询

反向查询

没有关联关系的哪一方成为反向--也就是一的哪一方 -- 表名小写

正向和反向查询
正向 ----> 关联字段在当前表中,从当前表向外查叫正向
反向 —> 关联字段不在当前表中,当当前表向外查叫反向
正向通过字段,反向通过表名查

一对一 OneToOneField

# 一个文章详情表一对一关联文章表,相当于Foreignkey 加unique
class Article(models.Model):
	nid = models.AutoField(primary_key=True)
	desc = models.CharField(max_length=255)
	
class ArticleDetail(models.Model):
    """
    文章详情表
    """
    nid = models.AutoField(primary_key=True)
    content = models.TextField()
    article = models.OneToOneField(to="Article", to_field="nid",on_delete=models.DO_NOTHING)

正向:

1、基于对象:obj.(外键).属性

ArticleDetail_obj = models.ArticleDetail.objects.filter(pk=pk).first()
ArticleDetail_obj.article.desc

2、基于字段跨表查询:外键__属性

models.ArticleDetail.objects.filter(pk=2).values("article__desc")

反向:从详情查文章

1、基于对象:obj.(表名小写).属性

article_obj = models.Article.objects.filter(pk=pk).first()
article_obj.articledetail.content

2、基于字段跨表查询:表名小写__属性

models.Article.objects.filter(id=1).values('articledetail__content')

一对多 ForeignKey

book – > publish :一个出版社有多个书

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    # 与Publish建立一对多的关系
	publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)

正向

1、基于字段:obj.(外键).属性

book_obj = models.Book.objects.filter(title='红楼梦').first()
book_obj.publish.name

反向:obj.(表名小写_set).all()
1、set查询

publish_obj=models.Publish.objects.filter(name="教育").first()
books = publish_obj.book_set.all()
for book in books:
	print(book.title)

多对多 ManyToManyField

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()

    # 与AuthorDetail建立一对一的关系
    authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()
    
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)

    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors=models.ManyToManyField(to='Author',)

正向:

1、基于字段:obj.(外键).all()

book_obj = models.Book.objects.filter(title="python教程").first()
authors = book_obj.authors.all()
for author in authors:
	print(author.name,author.age)

反向:obj.(表名小写_set).all()
1、set查询

author_obj = models.Author.objects.filter(name="moke").first()
books = author_obj.book_set.all()
for book in books:
	print(book.title)

2、related_name查询

author_obj.related_name.all()

常用字段

AutoField       自增  primary_key = True主键

IntegerField    整形 -21亿  - 21亿

BooleanField     布尔值类型

NullBooleanField  可以为空的布尔值

CharField      字符串

TextField      文本类型

DateTimeField   日期+加时间

DateField     日期格式
    
TimeField     时间格式

FloatField    浮点型

DecimalField(max_difits=6,decimal_piaces=3)   十进制小数

字段参数

null = True    数据库中该字段可以为空

black = True    用户输入可以为空

default         默认值

db_index=True 索引

unique    唯一约束

verbose_name   显示的名称

choices   可选择的参数

必知必会十三条

返回对象列表  QuerySet
all()      所有的对象
filter()    获取满足条件的所有对象
exclude()   获取不满足条件的所有对象
order_by()   排序   - 
reverse()   反转
values()    [ {}  ]
values_list()    [ ()  ]
distinct()   去重  不能按照字段去重

返回对象
get()    获取有且唯一的对象
first()
last()

返回数字
count

返回布尔值
exists() 

单表的双下划线

字段__条件
__gt   大于
__gte   大于等于
__lt  小于
__lte   小于等于
__in= []    成员判断
__range = [3,6]  范围  3-6

__contains =''    包含   like
__icontains =''   忽略大小写

__startswith =''   以什么开头
__istartswith =''   以什么开头


__endswith =''   以什么结尾
__endswith =''   以什么结尾


__year ='2019'  

__isnull = True   字段值为null 
posted @ 2021-04-01 14:54  赵刚、  阅读(142)  评论(0编辑  收藏  举报