Django之ORM操作(聚合 分組、F Q)


Django之ORM操作(聚合 分組、F Q)

  

  聚合

  aggregate()是QuerySet的一個終止子句,也就是說,他返回一個包含一些鍵值對的字典,在它的后面不可以再進行點(.)操作.

    鍵的名稱是聚合值的標識符,只是計算出來的聚合值.鍵的名稱是按照字段和聚合函數的名稱自動生成出來的.

  聚合函數的導入

from django.db.models import Max, Min, Sum, Avg, Count

  

  簡單使用示例:

  查詢所有書的平均價格.

1 from django.db.models import Avg, Sum, Max, Min, Count
2 
3 ret = models.Book.objects.all().aggregate(Avg("price"))
4 
5 >>> {'price__avg': 13.233333}  # price__avg 是自動成出來的,前邊是聚合的字段,后邊是聚合函數的名稱.

  

   當需要為聚合值指定一個名稱,可以向聚合子句提供它.

from django.db.models import Avg, Sum, Max, Min, Count

models.Book.objects.aggregate(average_price=Avg('price'))  # average_price 為自己指定的名稱.
>>> {'average_price': 13.233333}

 

  當需要生成不止一個聚合時,可以向aggregate()子句中添加另一個參數.

 

  查詢所有圖書價格的平均值 最大值 最小值.

1 from django.db.models import Avg, Sum, Max, Min, Count
2 
3 models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price"))  # 
4 
5 >>> {'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}

 

  查詢所有圖書中最高的價格和平均價格

1 from django.db.models import Max, Avg
2 
3 ret = models.Book.objects.aggregate(Max('price'), avg=Avg('price'))  # 

 

   分組

   現有員工表如下:

 

   需求:

    按照部門分組求平均工資

  ORM操作如下:

1 from django.db.models import Avg
2 
3 models.Employee.objects.values("dept").annotate(avg=Avg("salary").values("dept", "avg")  # 

 

  按照哪個字段分組,就將哪個字段寫在objects后面的values中.

 

  注意:

    分組使用的是annotate(),他不是一個終止子句,他的后邊可以跟其他操作.

 

  連表查詢:

    表格如下:

 

   按照部門分組求平均工資:

1 from django.db.models import Avg
2 
3 models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")  # 

 

  按照部門分組,就從部門表上開始查,聚合函數Avg()中寫需要差的字段,按照雙下划線的方法找到字段.

 

  其他示例:

  統計每一本書的作者的數量

1 from app01 import models
2 from django.db.models import Count
3 
4 ret = models.Book.objects.annotate(Count('author')).values()  # 

 

   查詢每個出版社出版的圖書中價格最低的

 

  方式一:

1 from app01 import models
2 from django.db.models import Min
3 
4 ret = models.Publisher.objects.annotate(Min('book__price')).values()  # 

 

  從出版社表查,聚合函數Min()中寫需要查詢的字段,使用雙下滑線(__)的方法查詢到需要的字段.

 

   方式二:

1 from app01 import models
2 from django.db.models import Min
3 
4 ret = models.Book.objects.values('publisher__name').annotate(min=Min('price'))  # 

 

  從書表中查,objects后面的values()中寫分組依據的字段名.然后跟annotate()中寫聚合函數,聚合函數中寫查詢的字段.

 

  查詢作者大於1的圖書

1 from app01 import models
2 from django.db.models import Count
3 
4 ret = models.Book.objects.annotate(count=Count('author')).filter(count__gt=1).values()  # 

 

  從書表中查詢,先統計每一本書的作者的數量,然后使用filter()過濾出符合條件的對象.

 

  查詢每位作者所出書的總價格

1 from app01 import models
2 from django.db.models import Sum
3 
4 ret = models.Author.objects.annotate(Sum('books__price')).values()  # 

 

  從作者表查詢,聚合函數Sum()中填寫查詢的字段

 

  F

   在此之前我們構造的過濾器都只是將字段與某個常量作比較,如果將兩個字段做比較時,可以使用F().F()的實例可以再查詢中引用字段,來比較同一個model實例(對象)中的兩個不同字段的值.

  簡單點說就是可以用來動態數據對比查詢.

 

  F的導入

from django.db.models import F

 

  查詢銷量大於庫存的圖書

from django.db.models import F

ret = models.Book.objects.filter(sale__gt=F('kucun')).values()  # 

 

  F的用法是F('字段名'),F()是用來取值的.

 

  將所有書的銷量更新為原來的2倍.

1 from app01 import models
2 from django.db.models import F
3 
4 ret = models.Book.objects.all().update(sale=F('sale') * 2)  # 

 

  可以進行翻倍操作.

 

  PS:

    知識補充 ---> .update()  更新

    僅對選中的QuerySet對象進行更新,速度快.

1 from app01 import models
2 
3 ret = models.Book.objects.filter(id=2).update(sale=100)  # 

 

  將id為2的書的銷量設置為100.

 

  將所有書的銷量更新為原來的2倍.

1 from app01 import models
2 from django.db.models import F 3 4 ret = models.Book.objects.all().update(sale=F('sale') * 2) # 

 

  可以進行翻倍操作.

 

    知識補充 ---> .save()  修改后進行保存.

    對所有對象都進行保存,操作數據量大,速度慢.

1 from app01 import models
2 
3 obj = models.Book.objects.get(id=2)
4 obj.sale='1000'
5 obj.save()

 

  將id為2的書的銷量設置為1000.

 

  Q

     filter()等方法中的關鍵字參數查詢都是一起進行'and'的,如果需要進行更加復雜的查詢,可以使用Q對象.

  示例:

    查詢id小於等於3或者id大於等於6的書

1 from app01 import models
2 from django.db.models import Q
3 
4 ret = models.Book.objects.filter(Q(id__lte=3) | Q(id__gte=6))  # 

 

    Q()寫在filter()中,使用或(or)查詢是每個Q()使用管道符(|)連接,管道符表示或(or)的關系.

 

    查詢id大於等於10並且銷量大於等於3000的書.

1 from app01 import models
2 from django.db.models import Q
3 
4 ret = models.Book.objects.filter(~Q(price__gte=10) & Q(sale__gte=3000)).values()  # 

  

  使用&連接時表示and.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM