django中的跨表查詢梳理

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對象
注意:在ForeignKey()和ManyToManyField()能夠設置related_name的值來賦值FOO_set
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給咱們提供了這兩種查詢方法。
  • F()
# 查詢評論數大於收藏數的書籍
 from django.db.models import F
    
 Book.objects.filter(commnetNum__lt=F('keepNum'))

# 將每本書的價格提升30
Book.objects.all().update(price=F("price")+30) 
  • Q()
bookList=Book.objects.filter(Q(author__name="a")|Q(author__name="b"))

8.總結

數據的操做,每每是項目中的關鍵一步,理清楚數據間的關係和查詢方法,更有助於程序的開發。
相關文章
相關標籤/搜索