Django-model聚合查詢與分組查詢
- 聚合函數包含:SUM AVG MIN MAX COUNT
- 聚合函數可以單獨使用,不一定要和分組配合使用;不過聚合函數一般和group by 搭配使用
- aggregate()是QuerySet 的一個終止子句,意思是說,它返回一個包含一些鍵值對的字典。
- 分組查詢 annotate 查詢出來的結果任然是集合是QuerySet類型;
- annotate對獲取的集合進行分組,按照集合的個數分組;
聚合查詢的使用aggregate()來調用
1.查詢所有書籍的總價格
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
# 統計所有書籍的總價格 aggregate 用來調用聚合函數的
# 可以通過binming= 來定義別名為 binming
book_list=models.Book.objects.all().aggregate(binming=Sum("price"))
print(book_list)
return HttpResponse("OK")
輸出:
{'binming': Decimal('5144.00')}
2.查詢出所有書籍的平均價格
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_list=models.Book.objects.all().aggregate(AVG_binming=Avg("price"))
print(book_list)
return HttpResponse("OK")
輸出:
{'AVG_binming': 16.12539184952978}
3.同時查詢出,這些書籍的平均值,最大值,和最小值
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_list=models.Book.objects.all().aggregate(Avg("price"),Max("price"),Min("price"))
print(book_list)
return HttpResponse("OK")
輸出:
{'price__max': Decimal('111.00'), 'price__min': Decimal('11.00'), 'price__avg': 16.12539184952978}
分組查詢 annotate()來調用
1.統計書本有作者的記錄,並求出該書有 幾個作者
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_obj=models.Book.objects.filter(authors__age__gt=0).annotate(c=Count("authors"))
print(book_obj.values_list("title","c"))
return HttpResponse("OK")
輸出:
<QuerySet [('三國演義', 3), ('紅樓夢1', 1), ('李四的歌', 1), ('ccc', 3)]>
2.統計每個出版社,出版書籍價格的總和
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_obj=models.Publish.objects.all().annotate(c=Sum("book__price"))
print(book_obj.values_list("name","c"))
return HttpResponse("OK")
輸出:
<QuerySet [('小黃人出版社', Decimal('595.00')), ('小紅帽出版社', Decimal('4428.00')), ('紅太陽出版社', Decimal('121.00'))]>
3.統計每個出版社,出版過的書籍數量
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_obj=models.Publish.objects.all().annotate(c=Count("book__title"))
print(book_obj.values_list("name","c"))
return HttpResponse("OK")
輸出:
<QuerySet [('小黃人出版社', 30), ('小紅帽出版社', 284), ('紅太陽出版社', 5)]>
4.通過Book表查出每個出版社出版過書籍的本數;
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
# 先獲取所有的書本集合set,根據集合取出出版社對象幾個;按照出版社集合分組,計數出版社出版的書籍數量
book_obj=models.Book.objects.all().values_list("publisher__name").annotate(c=Count("title"))
# 取出出版數量c ,以及出版社的名稱
print(book_obj.values_list("c","publisher__name"))
return HttpResponse("OK")
5.統計出書名以"三"開頭的書籍,作者的個數;
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_obj=models.Book.objects.filter(title__startswith="三", authors__age__gt=0).annotate(c=Count("authors"))
print(book_obj.values_list("c","title"))
return HttpResponse("OK")
輸出:
<QuerySet [(3, '三國演義'), (2, '三毛流浪記')]>
6.統計作者個數大於一個人的書籍
from django.db.models import Avg,Count,Min,Max,Sum
def juheQuery(request):
book_obj=models.Book.objects.all().annotate(c=Count("authors")).filter(c__gt=1)
print(book_obj.values_list("c","title"))
return HttpResponse("OK")
輸出:
<QuerySet [(3, '三國演義'), (3, 'ccc'), (2, '三毛流浪記')]>
F查詢與Q查詢
- F()的實例可以在查詢中引用字段,來比較同一個 model 實例中兩個不同字段的值。
- F()也可以用來做直接的運算;
F查詢(可以獲取某個字段值):
1.查詢出,評論數大於閱讀數的書籍
from django.db.models import F,Q
def FQQuery(request):
book_obj=models.Book.objects.filter(comment_num__gt=F("read_num"))
print(book_obj.values_list("title"))
return HttpResponse("OK")
輸出:
<QuerySet [('小兵張嘎',), ('人魚傳說',), ('小紅書',), ('小紅書',), ('小紅書',), ('三國演義',)]>
2.查詢出,評論數是閱讀數2倍的書籍;
from django.db.models import F,Q
def FQQuery(request):
book_obj=models.Book.objects.filter(comment_num__gt=F("read_num")*2)
print(book_obj.values_list("title"))
return HttpResponse("OK")
輸出:
<QuerySet [('人魚傳說',), ('小紅書',), ('小紅書',), ('小紅書',), ('三國演義',)]>
3.將所有的書籍價格+10
from django.db.models import F,Q
def FQQuery(request):
models.Book.objects.all().update(price=F("price")+10)
return HttpResponse("OK")
Q 查詢:使用(|或 &且)
1.評論數大於100或閱讀數大於100的書本---|
from django.db.models import F,Q
def FQQuery(request):
book_obj=models.Book.objects.filter(Q(comment_num__gt=100)|Q(read_num__gt=100))
print(book_obj.values_list("title"))
return HttpResponse("OK")
輸出:
<QuerySet [('人魚傳說',), ('三國演義',)]>
ORM修改和ORM刪除
1.ORM修改
1 obj.name="egon" obj.save() 效率低
2 表.objects.all().update(name="") 推薦
注意點:update方法是QuerySet數據類型的方法。model對象不能調用。
2.ORM刪除
表.objects.filter().delete()
注意事項:
1 、 delete()是QuerySet數據類型的方法
2 、 級聯刪除