一..基於雙下划線的跨表查詢(join實現)
key:正向查詢按字段,反向查詢按表明小寫
1.一對多跨表查詢

1 查詢在跨表中可以有兩種方式,正向查詢就是關鍵字段在你要搜索的表,沒有關鍵字段就是反向查詢 2 跨表查詢的顯著特點是__雙下划線,這道題中在你要找到name,但是Book中沒有,通過正向查詢關鍵字段+__來 3 跨表找到name 4 ret=Book.objects.filter(title="python").values("publish__name") 5 # print(ret) 6 ret=Publish.objects.filter(book__title="python").values("name") 7 print(ret) <QuerySet [{'name': '雲南出版社'}]>

1 2 查詢小瑞出版社出版的所有的書籍的名稱 2 這道題中反向解析在出版社開始找,但是條件沒有'小瑞',跨表尋找條件, 3 在filter條件先通過反向查詢表名小寫__+條件找到 4 ret=Book.objects.filter(publish__name="小瑞").values("title") 5 print(ret) 6 ret=Publish.objects.filter(name="小瑞").values("book__title") 7 print(ret)<QuerySet [{'book__title': 'linux'}, {'book__title': 'css'}]>
2.多對多

1 3 查詢python這本書籍的作者的年齡 2 在多對多的環境下,和一對多查詢一樣,是因為django是在太過強大,通過字段和表名小寫 3 將多對多關系的三張表統統間接在一起,各取所需, 4 ret=Book.objects.filter(title="linux").values("authors__age") 5 print(ret)<QuerySet [{'authors__age': 18}, {'authors__age': 25}]> 6 ret=Author.objects.filter(book__title="linux").values("age") 7 print(ret)

1 4 查詢alex出版過的所有的書籍名稱 2 ret=Author.objects.filter(name="alex").values("book__title") 3 print(ret)<QuerySet [{'book__title': 'python5'}, {'book__title': 'linux'}, {'book__title': 'css'}]> 4 ret=Book.objects.filter(authors__name="alex").values("title") 5 print(ret)
3.一對一

1 5 查詢alex的手機號 2 ret=Author.objects.filter(name="alex").values("ad__tel") 3 print(ret)<QuerySet [{'ad__tel': 123}]> 4 ret=AuthorDetail.objects.filter(author__name="alex").values("tel") 5 print(ret) 6 6 查詢手機號為110的作者的名字 7 ret=AuthorDetail.objects.filter(tel="234").values("author__name") 8 print(ret)<QuerySet [{'author__name': 'egon'}]> 9 ret=Author.objects.filter(ad__tel="234").values("name") 10 print(ret)
聰明的你不難發現只要掌握了查詢方式key,都是一樣的
4.多個表單連續查詢

1 1.查詢小瑞出版社出版過的所有書籍的名字以及作者的姓名 2 這里可以通過表之間的關系逐步連成一張大表查詢,注意的是連接時 3 是正向還是反向查詢 4 ret=Publish.objects.filter(name="小瑞").values("book__title","book__authors__name") 5 print(ret)<QuerySet [{'book__title': 'linux', 'book__authors__name': 'alex'}, {'book__title': 'css', 'book__authors__name': 'alex'}, {'book__title': 'linux', 'book__authors__name': 'egon'}, {'book__title': 'css', 'book__authors__name': 'egon'}]> 6 ret=Author.objects.filter(book__publish__name="小瑞").values("name","book__title") 7 print(ret)
二>
聚合,分組
聚合與分組的區別是,聚合顯示的是 aggregate 后面的結果,如
而分組后的結果往往是以all() 分組的話 ,前面不寫values().如
一個個queryset對象列表,,需要values 來取出接軌
要是在values為條件分組的話,顯示的是values()里面的條件和annotate后面的函數 組成鍵值對
要是在條件的后面寫上了values(),按照具體要求分組,則是會是按你的要求分組
1.聚合

1 #聚合 2 #查詢所有作者的平均年齡 3 #聚合分組前一定要引入模塊,才會有效 4 from django.db.models import Avg,Max,Sum,Min,Count 5 # 查詢坐着的平均年齡 6 # ret=Author.objects.aggregate(Avg("age")) 7 # print(ret){'age__avg': 21.6667} 8 # # 查詢所有書籍的個數 9 # ret=Book.objects.aggregate(c=Count("title")) 10 # print(ret) {'c': 4}
2.分組

1 單表分組查詢 2 這里的結果就是一個由title 與 c 組成的鍵值對 3 查詢書籍表每一個出版社id以及對應的書籍個數 4 ret=Book.objects.values("title").annotate(c=Count(1)) 5 print(ret)<QuerySet [{'title': 'python5', 'c': 1}, {'title': 'python', 'c': 1}, {'title': 'linux', 'c': 1}, {'title': 'css', 'c': 1}]> 6 # 查詢每一個部門的名稱以及對應員工的平均薪水 7 ret=Author.objects.values("name").annotate(a=Avg("age")) 8 print(ret)<Que

1 跨表分組查詢 2 在跨表分組中,可以在函數中使用跨表,也可以在后面的values()進行取鍵值對的跨表,和跨表查詢一樣 3 查詢每一個出版社的名稱以及對應的書籍平均價格 4 ret=Publish.objects.annotate(c=Avg("book__price")).values("book__title","book__price","email") 5 print(ret)<QuerySet [{'book__title': 'python5', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'python', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'linux', 'book__price': Decimal('100.00'), 'email': '123'}, {'book__title': 'css', 'book__price': Decimal('150.00'), 'email': '123'}]> 6 查詢每一個作者的名字以及出版的書籍的最高價格 7 ret=Author.objects.values("name").annotate(c=Max("book__price")) 8 print(ret)<QuerySet [{'name': 'alex', 'c': Decimal('150.00')}, {'name': 'egon', 'c': Decimal('150.00')}, {'name': 'zero', 'c': None}]> 9 查詢每一個書籍的名稱以及對應的作者的個數 10 ret=Book.objects.values("pk").annotate(c=Count("authors")) 11 print(ret) 12 ret=Book.objects.annotate(c=Count("authors")) 13 print(ret) 14 4 查詢作者數不止一個的書籍名稱以及作者個數 15 ret=Author.objects.annotate(c=Count("book__title")).filter(c__gt=1).values("book__title","c") 16 print(ret) 17 ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c") 18 print(ret)<QuerySet [{'title': 'python5', 'c': 2}, {'title': 'linux', 'c': 2}, {'title': 'css', 'c': 2}]> 19 5 根據一本圖書作者數量的多少對查詢集 QuerySet進行排序 20 ret=Book.objects.annotate(c=Count("authors__name")).order_by("c") 21 print(ret)<QuerySet [<Book: Book object (2)>, <Book: Book object (1)>, <Book: Book object (4)>, <Book: Book object (3)>]> 22 6 統計每一本以py開頭的書籍的名稱以及作者個數 23 ret=Book.objects.annotate(c=Count("authors__name")).filter(title__startswith="py").values("title") 24 print(ret)
3.F與Q
F是在filter中,比如說進行兩個變量的比較,之類的用F函數
在這之前需要引入函數
from django.db.models import F,Q

1 from django.db.models import F,Q 2 # 查詢評論數大於100的所有的書籍名稱 3 ret=Book.objects.filter(count_num__gt=1000).values("title") 4 print(ret) 5 # 查詢評論數大於2倍點贊數的所有的書籍名稱 6 ret=Book.objects.filter(count_num__gt=F("poll_num")) 7 print(ret) 8 # 查詢評論數大於2倍點贊數的所有的書籍名稱 9 Book.objects.filter(count_num__gt=F("poll_num")*2) 10 ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000)) 11 print(ret)
Q函數則是進行條件的判斷時,比如價格>100或者地址在xxx"",通過比較的函數對比出來
& 和 |或 ~非
ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000))
print(ret)