多表操作,常用非常用字段
1基于双下划线的跨表查询
套路一样,用__跨表
-一对多
-多对多
2 聚合查询
-聚合函数
from django.db.models import Avg,Count,Max,Min,Sum
# 计算所有图书的平均价格
# ret=Book.objects.all().aggregate(Avg('price'))
# print(ret)
3分组查询
终极总结:
values在前,表示group by,在后,表示取值
filter在前,表示过滤(where),在后,表示having(对分组之后的结果再进行过滤)
4 F查询与Q查询
-F为了字段=后面的值,不能放字段,所以用F函数包裹一下就可以了
-Q为了构造与&,或|,非~的关系
5 常用字段:必须记住,非常用字段,了解即可
6 orm字段参数:
-null 可以为空
-unique 唯一性约束
-default 默认值
-db_index 为该字段建索引
-只给日期类型和时间类型用
-auto_now_add 新增数据时,默认把当前时间存入
-auto_now 修改的时候,默认把当前时间存入
7 关系字段
ForeignKey
-to 关联哪个表
-to_field 关联的字段
-related_name 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。(一般不要用)
-related_query_name :基于双下划线的反向查询之前按表名小写(一般不要用)
-on_delete:models.CASCADE,models.SET_NULL
-db_constraint:db_constraint=False代表,不做外键关联
代码;
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day77.settings") import django django.setup() from app01.models import * # 基于双 下划线的一对多查询 # 查询出版社为北京出版社出版的所有图书的名字,价格 # ret=Publish.objects.filter(name='北京出版社').values('book__name','book__price') # print(ret) # ret=Book.objects.filter(publish__name='北京出版社').values('name','price') # print(ret) # 查询北京出版社出版的价格大于19的书 # ret=Publish.objects.filter(name='北京出版社',book__price__gt=19).values('book__name','book__price') # print(ret) # 多对多 # 查询红楼梦的所有作者名字 # ret=Book.objects.filter(name='红楼梦').values('authors__name') # print(ret) # ret=Author.objects.filter(book__name='红楼梦').values('name') # print(ret) # 查询图书价格大于30的所有作者名字 # ret=Book.objects.filter(price__gt=30).values('authors__name') # print(ret) # 进阶练习--连续跨表 # 查询北京出版社出版过的所有书籍的名字以及作者的姓名 # ret=Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name') # print(ret) # ret=Book.objects.filter(publish__name='北京出版社').values('name','authors__name') # print(ret) # 手机号以151开头的作者出版过的所有书籍名称以及出版社名称 # ret=AuthorDetail.objects.filter(phone__startswith='13').values('author__book__name','author__book__publish__name') # print(ret) # ret=Book.objects.filter(authors__authordetail__phone__startswith='13').values('name','publish__name') # # print(ret) # 聚合查询aggregate from django.db.models import Avg,Count,Max,Min,Sum # 计算所有图书的平均价格 # ret=Book.objects.all().aggregate(Avg('price')) # print(ret) # 计算图书的最高价格 # ret=Book.objects.all().aggregate(Max('price')) # print(ret) #他是queryset的终止子句 # 计算图书的最高价格,最低价格,平均价格,总价 # # ret=Book.objects.all().aggregate(Max('price'),Min('price'),Avg('price'),Sum('price')) # print(ret) #分组查询annotate() # 统计每一本书作者个数 # ret=Book.objects.all().annotate(c=Count('authors')) # print(ret) # for r in ret: # print(r.name,'---->',r.c) # ret=Book.objects.all().annotate(c=Count('authors')).values('name','c') # print(ret) # 统计每一个出版社的最便宜的书(以谁group by 就以谁为基表) # ret=Publish.objects.all().annotate(m=Min('book__price')).values('name','m') # print(ret) # 统计每一本以py开头的书籍的作者个数 # ret1=Book.objects.all().filter(name__startswith='py').annotate(c=Count('authors')).values('name','c') # print(ret1) # 总结: group by 谁,就以谁做基表,filter过滤,annotate取分组,values取值 # 总结终极版本 # values在前,表示group by 在后,表示取值 # filter在前,表示where条件,在后表示having # 统计每一本以py开头的书籍的作者个数--套用模板 # ret2=Book.objects.all().values('name').filter(name__startswith='py').annotate(c=Count('authors')).values('name','c') # print(ret2) # 查询各个作者出的书的总价格 # ret=Author.objects.all().values('name').annotate(s=Sum('book__price')).values('name','s') # ret=Author.objects.all().annotate(s=Sum('book__price')).values('name','s') # print(ret) #查询名字叫lqz作者书的总价格 # ret=Author.objects.all().values('pk').filter(name='lqz').annotate(s=Sum('book__price')).values('name','s') # print(ret) # 查询所有作者写的书的总价格大于30 # ret=Author.objects.all().values('pk').annotate(s=Sum('book__price')).filter(s__gt=2).values('name','s') # ret=Author.objects.all().annotate(s=Sum('book__price')).filter(s__gt=30).values('name','s') # print(ret) # 总结终极版本 # values在前,表示group by 在后,表示取值 # filter在前,表示where条件,在后表示having # 统计不止一个作者的图书 ret=Book.objects.all().values('pk').annotate(c=Count('authors')).filter(c__gt=1).values('name','c') # ret = Book.objects.annotate(author_num=Count("authors")).filter(author_num__gt=1).values('name','author_num') print(ret)
1、ORM字段
AutoField: int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField: 一个整数类型,范围在 -2147483648 to 2147483647。
CharField: 字符类型,必须提供max_length参数, max_length表示字符长度。
DateField: 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField: 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
2、ORM字段参数
null:用于表示某个字段可以为空
unique:如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index: 如果db_index=True 则代表着为此字段设置索引。
default: 为该字段设置默认值。
DateField 和 DateTimeField
auto_now_add 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段。
3、关系字段
ForeignKey:外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。
to:设置要关联的表
to_field: 设置要关联的表的字段
related_name: 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
related_query_name: 反向查询操作时,使用的连接前缀,用于替换表名。
on_delete: 当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
models.DO_NOTHING
删除关联数据,引发错误IntegrityError
models.PROTECT
删除关联数据,引发错误ProtectedError
models.SET_NULL
删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT
删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
models.SET
删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
OneToOneField
to: 设置要关联的表。
to_field: 设置要关联的字段。
on_delete: 同ForeignKey字段
ManyToManyField
to: 设置要关联的表
symmetrical: 仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。
through:在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。
through_fields: 设置关联的字段。
db_table:默认创建第三张表时,数据库中表的名称。
元信息:
db_table: ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。
index_together: 联合索引。
unique_together: 联合唯一索引。
ordering:指定默认按什么字段排序。只有设置了该属性,我们查询到的结果才可以被reverse()。