7 多表操作
阿新 • • 發佈:2018-09-17
play 分隔 man pan 反向查詢 model bject 記錄 publish
一、多表之間的關系
1 一對一: 2 1?? 必須對先被關聯表添加記錄(即沒有外鍵的表) 3 2?? 關聯表中的關聯字段可以直接使用被關聯表時的對象 4 創建關聯表時,可直接使用外鍵 id 傳入被關聯表中未被綁定的元素 5 6 一對多: 7 1?? 必須對先被關聯表添加記錄(即沒有外鍵的表) 8 2?? 關聯表中的關聯字段可以直接使用被關聯表時的對象 9 3?? 過濾出被關聯表的對象記得加上 first() 處理 10 4?? 讓關聯表 id = 被關聯表 id 11 12 多對多: 13 1?? 添加關聯關系使用 book.authors.add(1,2),表示的是往中間表插入記錄,沒有返回值14 book:表示的是對應的 book 某本書,而不是在創建表時的 authors 屬性 15 1,2:表示的是 authors.id 16 2?? book.authors.add(*(1,2)) 17 3?? add(參數1,參數2) # 參數可以直接傳對象,以逗號分隔
1 解除綁定關系
remove() # 需要傳參數,參數即需要解除的 id 或者對象,可以是多個,用逗號分隔;也可用解壓的方式(*(參數1,參數2))
2 一次性清空綁定關系
clear() # 不用傳參數
3 先清空再設置
set() # 底層原理是先清空,然後再使用 add() 函數來添加;參數必須是可叠代對象
二、多表查詢的總結
authordetail = AuthorDetail.objects.filter(pk=zhf.authordetail_id) print(zhf.authordetail) # 這種情況下會查詢兩次,第一次是 authordetail 這個表中查詢一次;第二次是 zhf.authordetail 執行查詢一次Notice
1 正向查詢與反向查詢
正向查詢:關聯字段在 A 表中,查詢表 B,按字段來查詢,即 A.B.字段名 反向查詢:關聯字段在 A 表中,由表 B 查詢 表 A,按照 表名小寫_set 方式來查詢 如:B.a_set.all() B.a_set 是 Manage 對象 B.a_set.all() 是 QuerySet 對象
2 正向查詢方式與反向查詢方式
總結 | 正向查詢 | 反向查詢 |
one to one | 按照字段 | 表名小寫 |
one to many | 按照字段 | 表名小寫_set |
many to many | 按照字段 | 表名小寫_set |
三、基於雙下劃線的多表查詢(鏈表查詢)
Django 還提供了一種直觀而高效的方式在查詢(lookups)中表示關聯關系,它能自動確認 SQL JOIN 聯系。要做跨關系查詢,就使用兩個下劃線來鏈接模型(model)間關聯字段的名稱,直到最終鏈接到你想要的model 為止。
正向查詢按字段,反向查詢按表名小寫用來告訴ORM引擎join哪張表
1 在使用 __ 雙下劃線告訴 ORM 該 JOIN 哪張表前提下的總結
總結 | 正向查詢 | 反向查詢 |
one to one | 按照字段 | 表名小寫 |
one to many | 按照字段 | 表名小寫 |
many to many | 按照字段 | 表名小寫 |
四、聚合函數
form django.db.models.import Avg,Count,Max,Min,Sum # 使用 aggregate() 函數表示聚合函數 Book.objects.all.aggregate(Avg(‘price‘)) # 返回值是一個字典,可傳多個參數 # 給字段重命名 Book.objects.all.aggregate(avg_price=Avg(‘price‘))
五、分組
annotate() 為調用的 QuerySet 中每一個對象都生成一個獨立的統計值(統計方法用聚合函數)。
from django.db.models import Avg, Max, Sum, Min, Max, Count book_list = models.Book.objects.all().annotate(author_num=Count("authors")) for book in book_list: print(book.name) print(book.author_num) book_list = models.Book.objects.all().annotate(author_num=Count("authors")).values(‘name‘,‘author_num‘) print(book_list)
總結 :跨表分組查詢本質就是將關聯表 JOIN 成一張表,再按單表的思路進行分組查詢。
1?? value 在 annotate 前,表示group by 字段;在 annotate 後,表示要 select 的字段(若不寫 value,默認是以基表的主鍵為基準)
2?? filter 在 annotate 前,指的是 where 的東西;在 annotate 後面指的是 having 的東西
Notice
六、F 查詢和 Q 查詢
1 F 查詢
Django 提供 F() 函數。F() 的實例可以在查詢中引用字段,來比較同一個 model 實例中兩個不同字段的值。Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操作。修改操作也可以使用F函數。
from django.db.models import F,Q #評論數大於閱讀數的所有書,返回的是 QuerySet 對象 Book.objects.all().filter(commit_num__gt=F(‘read_num‘)) # 對所有的書價格 +1 Book.objects.all().update(price=F(‘price‘)+1)
2 Q 查詢
filter() 等方法中的關鍵字參數查詢都是一起進行“AND” 的。 若需要執行更復雜的查詢(例如 OR 語句),可以使用 Q 對象。
Q 對象可以使用 & 和 | 操作符組合起來。當一個操作符在兩個 Q 對象上使用時,它產生一個新的 Q 對象。
bookList=Book.objects.filter(Q(authors__name="888")|Q(authors__name="666"))
# 等同於 SQL 語句
WHERE name ="yuan" OR name ="egon"
如果出現Q 對象,它必須位於所有關鍵字參數的前面 bookList=Book.objects.filter(Q(publish_Date__year=9999) | Q(publish_Date__year=8888), name__icontains="Django")Notice
7 多表操作