django orm 基於雙下划線的跨表查詢


一..基於雙下划線的跨表查詢(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)
F函數

Q函數則是進行條件的判斷時,比如價格>100或者地址在xxx"",通過比較的函數對比出來

& 和  |或 ~非

ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000))
print(ret)

 


免責聲明!

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



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