1.前言
最近在寫一個小項目,裏面主要涉及的就是表與表之間複雜的關係。當真正開發起來的時候,才發現本身對複雜的表關係間的查詢有點混亂,趁着這幾天的時間,從新梳理了一下。
2.概念
在開始以前,先明確幾個基礎概念:
正向查詢:關聯字段所在的表查詢其關聯表叫正向查詢
反向查詢:未寫關聯字段的表查詢其關聯表叫反向查詢
# 書籍表
class Book(models.Model):
name = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish')
def __str__(self):
return self.t_name
# 出版社表
class Publish(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.t_name
# 根據書籍表,查詢其出版社,叫正向查詢
# 根據出版社,查詢書籍,叫反向查詢
3.一對多
book_obj=Book.objects.filter(pk=1).first() # 拿到書籍爲1對對象
publish_name = book_obj.publish.name # 根據字段查詢
# 查詢a出版社出版的書籍
book_list = Publish.book_set.all() # queryset對象
4.多對多
author_list = Book.objects.filter(pk=1).first().author.all()
# 多對多的關係,一本書查出來的做者多是多個,因此必定是一個queryset對象
Author.objects.filter(pk=1).first().book_set.all()
# 多對多的關係,一做者查出來的書多是多本,因此必定是一個queryset對象
class Book(model.Model):
publish = ForeignKey(Book, related_name='bookList')
# 查詢
Publish.objects.filter(pk=1).first().bookList.all()
5.基於雙下劃線的查詢
django還提供了一種直觀而高效的方式在查詢(lookups)中表示關聯關係,它能自動確認SQL JOIN 聯繫。要作跨關係查詢,就使用兩個下劃線來連接模型(model)間關聯字段的名稱,直到最終連接到你想要的model 爲止,一樣的,正向查詢按字段,反向查詢按表名小寫。
# 查詢a出版社出版的書的名字(name)和數量(num) 正向查詢,按字段
Book.objects.filter(publish__name='a出版社').values_list('naem','num')
# 查詢a出版社出版的書的名字(name)和數量(num) 反向查詢,按字段
Publish.objects.filter(name='a出版社').
values_lsit('book__name','book_num')
# 其實本質是同樣的,就是sql語句的select from的表不一樣而已
# 查詢a做者的書的名字(name)和數量(num) 正向查詢,按字段
Book.objects.filter(author__name='a').values_list('naem','num')
# 查詢a出版社出版的書的名字(name)和數量(num) 反向查詢,按字段
Author.objects.filter(name='a').
values_lsit('book__name','book_num')
6.分組查詢
annotate()爲調用QuerySet中每個對象都生成一個獨立的統計值,本質就是將關聯的表用sql語句中的join成一張表,再按單表查詢的方法進行操做。
7.django中的F查詢和Q查詢
在上面全部的例子中,咱們構造的過濾器都只是將字段值與某個常量作比較。而現實的需求中每每會有兩個字段的值作比較這樣的需求,django給咱們提供了這兩種查詢方法。
# 查詢評論數大於收藏數的書籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))
# 將每本書的價格提升30
Book.objects.all().update(price=F("price")+30)
bookList=Book.objects.filter(Q(author__name="a")|Q(author__name="b"))
8.總結
數據的操做,每每是項目中的關鍵一步,理清楚數據間的關係和查詢方法,更有助於程序的開發。