多表操作,常用非常用字段

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()。



 


posted @ 2018-11-14 18:29  zhouhao666  阅读(223)  评论(0编辑  收藏  举报