Django ORM表查询、聚合分组、F()和Q()函数

添加记录:
  添加记录方式1:
    Book.objects.create(title="三体",....)
  添加记录方式2:
    book=Book(title="三体",....)
    book.save()


1 查询记录:
  查询API:
    1 Book.objects.all()         # querysey [obj,....]
    2 Book.objects.filter(title="三体")    # querysey [obj,....]
      queryset.filter()          # 返回值 queryset

    3 Book.objects.exclude(title="三体")    # querysey [obj,....]   排除,不包括
    4 Book.objects.all().first()     # obj
    5 Book.objects.all().last()      # obj
    6 Book.objects.all()[0]       # obj
    7 Book.objects.get(title="三体")   # obj
    
    8 queryset.order_by()        # 返回值 queryset
    9 queryset.reverse()        # 返回值 queryset
    10 queryset.count()        # 返回值 int (queryset的终止函数)
        Book.objects.all().filter(price__gt=100).order_by("pirce").count()

    11 queryset.exist()        # 返回值是布尔值
    12 queryset.values("price")     # 返回值 queryset [{"price":123},{"price":124},{"price":13}]
    13 queryset.valueslist("price")     # 返回值 queryset [(123,),(124,),(345,)]
    14 queryset.distinct("price")        # 返回值 queryset       去重复

2 模糊查询 __  

  条件选取querySet的时候,filter表示=,exclude表示!=。

  querySet.distinct() 去重复
  __exact 精确等于 like 'aaa'
     __iexact 精确等于 忽略大小写 ilike 'aaa'
     __contains 包含 like '%aaa%'
     __icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。
  __gt 大于
  __gte 大于等于
  __lt 小于
  __lte 小于等于
  __in 存在于一个list范围内
  __startswith 以...开头
  __istartswith 以...开头 忽略大小写
  __endswith 以...结尾
  __iendswith 以...结尾,忽略大小写
  __range 在...范围内
  __year 日期字段的年份
  __month 日期字段的月份
  __day 日期字段的日
  __isnull=True/False


  Book.objects.filter(price__in=[100,200,300])
  Book.objects.filter(price__gt=100)
  Book.objects.filter(price__lt=100)
  Book.objects.filter(price__range=[100,200])
  Book.objects.filter(title__contains="x")
  Book.objects.filter(title__icontains="x")
  Book.objects.filter(title__startswith="py")
  Book.objects.filter(pub_date__year=2012)

3.跨表查询    数据查询

   

  1. 基于对象查询 ;拿到一个对象,要查与它的关联表中的数据。   (从一张表的对象找另外一张表的对象)

      ( 拿个对象出来,去查东西,可不就是点点点嘛 )

     一对一:OneToOne  直接 点点点  ;

     一对多:ForeignKey  正向 点点点  ;  反向 (肯定是集合)点yy_set.all()

     多对多:ManyToMany  正向 还是点点点(只不过这里点出来的是集合);  反向 (还是集合) 点yy_set.all()

 

  2.  基于链表查询   基于双下划线查询;  基于字段查询;         (从本表的对象、或者另外一张表的对象找需要的数据集(非对象))

     表现形式:双下划线 (即 连接起来两个表,相当于JOIN)        (也可以连续跨表)

      ( 现在还没有拿对象呢,就要给限制,还要跨表限制,限制做好了直接拿到所需要的对象 )(这样可不就是对字段提要求嘛)

   ( 没有对象呢,哪有点点点,只有杠杠杠 )

   

     Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。

   要做跨关系查询,就使用两个下划线来链接模型(model)。

     1 练习: 查询苹果出版社出版过的所有书籍的名字与价格(一对多)        

       queryResult=Book.objects.filter(publish__name="苹果出版社").values_list("title","price")       

         publish__   先说双下划线,表示JOIN链表;链哪张表呢?看前面publish,定义在本表中的外键且to=“Publish”,就表示链表Publish

         publish__   再加上name,就是Publish表中的 name 字段(列)

         queryResult=Publish.objects.filter(name="苹果出版社").values_list("book__title","book__price")             

          book__   先说双下划线,表示JOIN链表;链那张表呢?看前面book,就表示链表Book,前面小写了

            book__  再加上title,就是Book表中的 title 字段(列)

   

     2 练习: 查询alex出过的所有书籍的名字(多对多)

       queryResult=Book.objects.filter(authors__name="yuan").values_list("title", "price")                 

       queryResult=Author.objects.filter(name="yuan").values_list("book__title","book__price")              

         authors__name   表示 外键authors 指向的表Author中的name字段(列)

         book__title   表示的链表Book表,找title

4.高级查询:    聚合查询aggregate、注释查询annotate

    QuerySet.aggregate()    -->  Django的aggregate()方法作用是对一列值 ( 比如字段 ) 进行统计计算,并以字典(Dict)格式返回统计计算结果。

                 是QuerySet 的一个终止子句(也就是返回的不再是一个QuerySet集合的时候)

                 它返回一个字典。键的名称是标识符,值是计算出来的聚合值。

                 键是 "字段名__聚合函数名" 自动生成出来的。可以向聚合子句提供一个名。

                 Hobby.objects.annotate(age__max=Max(student__age))

   QuerySet.annotate()     -->    加注释。加注释意味着要加字段(modle)、加列(表)。

                   如果你想要对数据集先进行筛选分组(例如 filter)后再进行某些复杂的(聚合操作或排序)时,需要使用.annotate方法来注释。

                   给前一个紧挨着的结果集,加注释、加列(存复杂的聚合操作结果)。

                    Course.objects.filter(name__startswith='d').annotate(student_num=Count('student')).order_by('-student_num')[:5]

  参考https://www.cnblogs.com/jeavy/p/10926676.html


5、结合函数: models 的 F()与  Q()函数

  from django.db.models import F

  from django.db.models import Q

  1、F()函数

    F对象允许Django在未实际链接数据的情况下具有对数据库字段的值的引用。

    例如:

      BookInfo.objects.filter(auth="小明").update(price=F("price")+10)

  2、Q()函数

    Q对象是Django对model查询中所使用的关键字参数进行封装后的一个对象。
    Q对象可以通过 &(与)、 |(或)、 ~(非)运算来组合生成不同的Q对象,便于在查询操作中灵活地运用。

    例如:

      bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

  

    查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。

    但是,如果出现Q 对象,它必须位于所有关键字参数的前面。

ok

原文地址:https://www.cnblogs.com/kingon/p/9433509.html