zoukankan      html  css  js  c++  java
  • python-day71--django多表双下划线查询及分组聚合及F/Q查询

    #====================================双下划线的跨表查询===============
    # 前提 此时 related_name=bookList
    属性查询: # 查询linux这本书的出版社的地址? # linux_obj=models.Book.objects.filter(title="linux").first() # print(linux_obj.publish.name) # # # 查询老男孩出版社出版过的所有书籍的名字与价格 # # pubObj=models.Publish.objects.filter(name="老男孩出版社").first() # print(pubObj.bookList.all().values("title","price")) #此时 related_name=bookList 双下划线查询 : .filter(过滤的条件) .values(要显示的值)

      注意:如果在没有定义 related_name 时,反向查询时 直接用表名,不需要加 _set
    # 查询linux这本书的出版社的地址? --正向查询 #ret=models.Book.objects.filter(title="linux").values("publish__addr") # print(ret) #或                  --反向查询 # ret=models.Publish.objects.filter(bookList__title="linux").values("addr") # print(ret) # 查询老男孩出版社出版过的所有书籍的名字与价格 # ret1=models.Publish.objects.filter(name="老男孩出版社").values("bookList__title","bookList__price") # print(ret1) # # ret2=models.Book.objects.filter(publish__name="老男孩出版社").values("title","price") # print(ret2) #查询egon出过的所有书籍的名字(多对多) ret=models.Author.objects.filter(name="egon").values("bookList__title") print(ret) ret2=models.Book.objects.filter(authorlist__name="egon").values("title") print(ret2) # egon出版过的所有书籍名称以及出版社名称 ret=models.Book.objects.filter(authorlist__name='egon').values('title','Publish__name') # 手机号以151开头的作者出版过的所有书籍名称以及出版社名称 # 方法1: # ad=models.AuthorDetail.objects.filter(tel__startswith="151").first() # print(ad.author.bookList.all().values("title","publish__name")) # 方法2 models.Book.objects.filter(authorlist__authordetail__tel__startswith="151").values("title","publish__name")

    #================================================================聚合函数
      注明:下方的所有all() 都可以省略 。 不加values / values_list 得到的就是包含对象的QuerySet,加上了就是包含字典/元组的QuerySet
    
        from django.db.models import Avg,Sum,Count,Max,Min
    
        # 聚合函数:aggregate   
    # 查询所有图书的价格和 ret=models.Book.objects.all().aggregate(priceSum=Sum("price")) print(ret) # {'priceSum': Decimal('166.00')} ret=models.Book.objects.all().aggregate(priceAvg=Avg("price"),priceSum=Sum("price"))
       #单独使用aggregate 函数聚合时,返回的是 字典
    # 分组函数 annotate函数 # 查询每一本书的作者个数 book_list=models.Book.objects.all().annotate(c=Count("authorlist__name")) #此时的book_list 是一个QuerySet for book_obj in book_list: print(book_obj.c) #按照原来得所有字段进行分组-相当于与原表一样-,默认分成一组, 并且分组后会在新表中新增一个 c 的字段

      print(book_list)
      #结果:------------------------- <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Boo
      k: Book object>, <Book: Book object>]>

    # 查询每一个出版社出版过的最便宜的书籍 ret=models.Book.objects.all().values('publish__id').annotate(Min("price")) #values内的字段就是分组字段 print(ret)
     
      #结果:------------------------- <QuerySet [{'publish__id': 1, 'price__min': Decimal('120.00')}, {'publish__id': 2, 'price__min': Decimal('520.00')}, {'p
      ublish__id': 3, 'price__min': Decimal('222.00')}]>

      # 查询每一个出版社出版过的书籍个数
      ret=models.Book.objects.all().values('publish__id').annotate(c=Count('name'))    #values内的字段就是分组字段
      print('-------------------------',ret)
      #结果:------------------------- <QuerySet [{'publish__id': 1, 'c': 5}, {'publish__id': 2, 'c': 1}, {'publish__id': 3, 'c': 1}]>
         分组后得到的是一个QuerySet集合,里面得到的是字典形式的数据,并且只有分组依据和聚合函数的两个字段
    
    

    F  与 Q  查询

    F查询
    
    在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
    Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
    
    # 查询评论数大于收藏数的书籍
     
       from django.db.models import F
    
       Book.objects.filter(commnetNum__gt=F('keepNum'))
    
    Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
    
    # 查询评论数大于收藏数2倍的书籍
        Book.objects.filter(commnetNum__gt=F('keepNum')*2)
    
    修改操作也可以使用F函数,比如将每一本书的价格提高30元:
    
    Book.objects.all().update(price=F("price")+30)
    
    
     
    Q查询
    
    filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。
    
    from django.db.models import Q
    
    Q(title__startswith='Py')
    
    Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。
    
    bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
    
    等同于下面的SQL WHERE 子句:
    
    WHERE name ="yuan" OR name ="egon"
    
    你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:
    
    bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
    
    查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:
    
        bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")
  • 相关阅读:
    113. Path Sum II
    112. Path Sum
    111. Minimum Depth of Binary Tree
    110. Balanced Binary Tree
    Create
    SetWindowPos
    INT_PTR数据类型
    SDK介绍
    COLORREF
    setfont()函数
  • 原文地址:https://www.cnblogs.com/liuwei0824/p/7756295.html
Copyright © 2011-2022 走看看