• 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

  • 相关阅读:
    设计模式:迭代器模式(Iterator Pattern) 明
    设计模式:目录导航 明
    设计模式:状态模式(State Pattern) 明
    设计模式:命令模式(Command Pattern) 明
    二维DP—— POJ 3186
    COM组件里自动化接口与普通接口的转换
    贪心好题——poj3044
    三分查找——POJ3301
    静态链表+DFS——poj 3272
    妙用队列优化——校赛题
  • 原文地址:https://www.cnblogs.com/kingon/p/9433509.html
Copyright © 2020-2023  润新知