日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django ORM查询之外键、关系的反向引用

發布時間:2023/12/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django ORM查询之外键、关系的反向引用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關系本身就是相互的只用在一個表中記錄而不是在有關系的兩個表中都記錄所以外鍵關系提供反向引用機制當然外鍵可以是多個表的外鍵關系也可以與多個表有關系所以反向引用必須顯式指出關系對方表然后是字段)。而正向引用則不必因為正向引用在定義時就指定了關系對方表(Book::publisher = ForeignKey(‘Publisher’)、Book::authors = ManyToManyField(‘Author’) )

Joins and aggregates關系連接和集合函數

So far, we have dealt with aggregates over fields that belong to the model being queried. However, sometimes the value you want to aggregate will belong to a model that is related to the model you are querying.

到目前為止,我們已經在被查詢的模型的字段上處理了集合操作。然而,有時候你想要求集合的值屬于你查詢的模型的關聯的模型。

When specifying the field to be aggregated in an aggregate function, Django will allow you to use the same double underscore notation that is used when referring to related fields in filters. Django will then handle any table joins that are required to retrieve and aggregate the related value.

當在一個集合函數中指定要集合的字段Django將允許你像在filters中引用關聯字段時那樣使用兩下劃線符號Django之后將處理任何請求的表的連接以便檢索并集合關聯的值

For example, to find the price range of books offered in each store, you could use the annotation:

例如,要找到每家書店提供的書的單價范圍,你可以使用注釋:

#~~~~~~~

>>> from django.db.models import Max, Min

>>> Store.objects.annotate( min_price=Min('books__price'), max_price=Max('books__price') )

#對Store中單個記錄,按一對多關系連接books表,對一對多的所有books的price字段進行集集合算Min()、Max()

#~~~~~~~

This tells Django to retrieve the Store model, join (through the many-to-many relationship) with the Book model, and aggregate on the price field of the book model to produce a minimum and maximum value.

這告訴Django檢索Store模型,連接(通過多對多關系)Book模型,集合book模型的單價字段來生成最低和最高值。

Store模型:

id

name

books,存儲售賣的所有書,多對多關系

Book模型:

id

name

authors,存儲所有為本書貢獻了的作者,多對多關系

price

Author模型:

id

name

age

?

關系就是要來告訴數據庫去連接的。

The same rules apply to the aggregate() clause. If you wanted to know the lowest and highest price of any book that is available for sale in any of the stores, you could use the aggregate:

同樣的規則也應用于集合aggregate()子句。

#~~~~~~

>>> Store.objects.aggregate( min_price=Min('books__price'), max_price=Max('books__price') )

#Store模型的books關系字段__關系連接的Book模型的price字段

#~~~~~~

Join chains can be as deep as you require. For example, to extract the age of the youngest author of any book available for sale, you could issue the query:

連接鏈可以如你所需要的深度那么深。例如,提取售賣的任意書的最年輕的作者的年齡,你可以這樣處理查詢:

#~~~~~~~~~

Store.objects.aggregate( yongest_author_age = Min(‘books__authors__age’) )

#Store模型的books關系字段__連接的Book模型的authors關系字段__連接的Author模型的age字段

#~~~~~~~~~

?

Following relationships backwards

In a way similar to Lookups that span relationships, aggregations and annotations on fields of models or models that are related to the one you are querying can include traversing “reverse” relationships. The lowercase name of related models and double-underscores are used here too.

以類似于跨關系查找的方式在模型或關聯到你正在查詢的模型的模型的字段上進行集合和注釋可以包括遍歷反向關系這里也用到了關聯模型的名字的小寫與兩下劃線

Store模型:

id

name

books,存儲售賣的所有書,多對多關系

Book模型:

id

name

authors,存儲所有為本書貢獻樂的作者,多對多關系,多值字段

pubdate

rating

pages

publisher,外鍵,數據庫中存儲所引用的外鍵的主鍵,可以多對一關系Publisher模型記錄

price

關系本身就是相互的只用在一個表中記錄而不是在有關系的兩個表中都記錄所以外鍵關系提供反向引用機制當然外鍵可以是多個表的外鍵關系也可以與多個表有關系所以反向引用必須顯式指出關系對方表然后是字段)。而正向引用則不必因為正向引用在定義時就指定了關系對方表(Book::publisher = ForeignKey(‘Publisher’)、Book::authors = ManyToManyField(‘Author’) )

Author模型:

id

name

age

Publisher模型:

id,主鍵,作為Book模型publisher字段的外鍵,可以一對多關系Book模型記錄

name

?

For example, we can ask for all publishers, annotated with their respective total book stock counters (note how we use 'book' to specify the Publisher -> Book reverse foreign key hop):

例如,我們可以請求所有出版商,對他們對應的總同屬存貨計數(注意我們如何使用’book’指定Publisher ->Book反向外鍵跳躍):

#~~~~~~

>>> from django.db.models import Avg, Count, Min, Sum

>>> Publisher.objects.annotate( Count('book') )

#’book’——Publisher被外鍵引用的Book模型,對反向外鍵關系的Book模型的所有記錄計數反向外鍵引用必須顯式指定反向外鍵引用的表book統計的話不用再加字段) )

#~~~~~~

(Every Publisher in the resulting QuerySet will have an extra attribute called book__count.)

結果查詢集中的每個Publisher將具有一個特殊的屬性(注釋列,只存在于返回的查詢集上)稱作book__count。

We can also ask for the oldest book of any of those managed by every publisher:

我們也可以請求每個出版商管理的書籍中最老的書(Book模型的publisher外鍵引用Poblish模型,為此Poblisher模型需要反向外鍵引用Book模型):

#~~~~~~~~~

我想的:Publisher.objects.annotate( oldest_book = Min(‘book__pubdate’) )

#為Publisher模型的每個記錄注釋一個’oldest_book’,對反向外鍵關系Book模型的pubdate最小的那個book實例反向外鍵引用必須顯式指定反向外鍵引用的表book,再加其一個字段

>>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))

#官檔為Publisher模型的每個記錄返回一個包含名字’oldest_pubdate’的字典,值就是反向關系(一個Publisher對應多個Book的)

#~~~~~~~~~~

返回的結果字典將有一個稱作’oldest_pubdate’的鍵如果不指定別名將會是很長的’book__pubdate_min’(包含引用鏈的字段名__集合類名(集合函數名) )

This doesn’t apply just to foreign keys. It also works with many-to-many relations. For example, we can ask for every author, annotated with the total number of pages considering all the books the author has (co-)authored (note how we use 'book' to specify the Author -> Book reverse many-to-many hop):

反向引用不僅能應用到外鍵還可以應用到多對多關系例如我們可以請求每個作者注釋該作者參與編輯的所有書的總頁數注意我們是如何使用’boo’去指定Author -> Book反向多對多跳躍的

#~~~~~~~~~~

>>> Author.objects.annotate( total_pages=Sum('book__pages') )

#外鍵和關系都可以被反向引用反向引用時必須顯式指出反向引用的表名的小寫book。這里將Book模型的author多對多關系Author模型進行了反向,Author模型反向多對多關系Book模型的pages字段

#~~~~~~~~~~

結果查詢集中的每個Author將會具有一個額外的屬性稱作total_pages。如果不指定這樣的別名,將會是很長的’book__pages__sum)。

?

Or ask for the average rating of all the books written by author(s) we have on file:

或者請求我們在文件中存在的作者所寫的所有書的平均評分:

#~~~~~~~~~~

Author.objects.annotate( avg_rating = Avg(‘book__rating’) )

Author.objects.aggregate( avg_rating = Avg(‘book__rating’) )

#~~~~~~~~~~

結果字典將具有一個稱作’avg__rating’的鍵。如果不指定這樣一個別名,將會是挺長的’book__rating__avg’。

?

Aggregations and other QuerySet clauses

filter() and exclude()

Aggregates can also participate in filters. Any filter() (or exclude()) applied to normal model fields will have the effect of constraining the objects that are considered for aggregation.

集合也可以參與到filters中。任何應用到正常模型字段上的filter()或exclude()將具有約束考慮使用集合aggregation的對象的作用。

When used with an annotate() clause, a filter has the effect of constraining the objects for which an annotation is calculated. For example, you can generate an annotated list of all books that have a title starting with “Django” using the query:

當與一個annotate()子句一起使用時,過濾器具有約束為其計算注釋的對象的作用。例如,使用查詢,你可以為標題以’Django’開頭的所有書籍生成一個注釋列。

#~~~~~~~

>>> from django.db.models import Avg, Count

>>> Book.objects.filter( name__startswith="Django" ).annotate( num_authors=Count('authors') )

#過濾返回一個查詢集,總是可以為查詢集增加注釋列

#~~~~~~~

When used with an aggregate() clause, a filter has the effect of constraining the objects over which the aggregate is calculated. For example, you can generate the average price of all books with a title that starts with “Django” using the query:

當與一個集合aggregate()子句一起使用,過濾器具有約束為其計算集合的對象的作用。例如,使用查詢,你可以為標題以’Django’開頭的所有書籍生成平均單價。

#~~~~~~~~

Book.objects.filter( name__startswith=’Django’ ).aggregate( avg_price = Avg(price) )

#這里既然Book記錄的price是一個single值,則Avg(price)是對查詢集所有記錄的price求均值。并返回單個字典avg_price:值。像下面:

#~~~~~~~

#~~~~~~~~

>>> from django.db.models import Avg, Max, Min

>>> Book.objects.aggregate( Avg('price'), Max('price'), Min('price') ) #Manager::aggregate()對全集計算集合意味的值返回這些值的字典

{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

#因為Book記錄的price是一個FloatField()值字段所以Avg(‘price’)、Max(‘price’)、Min(‘price’)是對查詢集所有記錄的price進行集合處理并返回單個字典

#~~~~~~~~

#~~~~~~

>>> q = Book.objects.annotate( num_authors=Count('authors') )

>>> q[0].num_authors

2

>>> q[1].num_authors

1

#因為Book記錄的authors是MantToManyField多對多字段,所以Count(‘authors’)是對Book記錄的一對多authors字段的集合aggregate處理,對每個Book記錄返回各自的注釋列。

#~~~~~~

Filtering on annotations

Annotated values can also be filtered. The alias for the annotation can be used in filter() and exclude() clauses in the same way as any other model field.

被注釋的值也可以被過濾注釋列的別名可以用在filter()exclude()子句中以與其他模型字段相同的方式

For example, to generate a list of books that have more than one author, you can issue the query:

例如,生成具有兩位及以上作者的書的列表,你可以這樣處理查詢:

#~~~~~~~~~

Books.objects.annotate( num_authors = Count(‘authors’) ).filter( num_authors__gte=2 )

Books.objects.annotate( num_authors = ExpressionWrapper( Count(‘authors’), output_field = IntegerField())?).filter( num_authors__gte=2 )

#~~~~~~~~

This query generates an annotated result set, and then generates a filter based upon that annotation.

這個查詢集生成一個注釋后的結果查詢集,然后基于這個注釋后的查詢集生成一個過濾后的查詢集。

If you need two annotations with two separate filters you can use the filter argument with any aggregate. For example, to generate a list of authors with a count of highly rated books:

如果你需要兩個注釋,使用兩個單獨的過濾,你可以使用filter參數在任意繼承中。例如,生成authors的一個列表,帶每個作者較高評分(7星及以上的)的著作的計數:

#~~~~~~~~

>>> highly_rated = Count( 'book', filter=Q(book__rating__gte=7) )

>>> Author.objects.annotate( num_books=Count('book'), highly_rated_books=highly_rated )

#num_books是每個Author實例的著作數(反向關系'book'+Count集合),highly_rated_books是每個Author的著作中評分大于等于7分的著作計數(反向關系'book'+過濾+Count集合,封裝查詢條件的Q實例對象要放在其他實參’book’后面)

#上面Count()是構造的models.Count類實例對象,不是Manager類或QuerySet類的count()實例方法。

Help on class Count in module django.db.models.aggregates:

?

class Count(Aggregate)

?| ?Count(*args, **kwargs)

?| ?

?| ?An SQL function call.

?| ?

?| ?Method resolution order:

?| ?????Count

?| ?????Aggregate

?| ?????django.db.models.expressions.Func

?| ?????django.db.models.expressions.SQLiteNumericMixin

?| ?????django.db.models.expressions.Expression

?| ?????django.db.models.expressions.BaseExpression

?| ?????django.db.models.expressions.Combinable

?| ?????builtins.object

?| ?

?| ?Methods defined here:

?| ?

?| ?__init__(self, expression, filter=None, **extra)?#expression可以是要集合操作的字段,filter是查詢子句

?| ?????Initialize self. ?See help(type(self)) for accurate signature.

#~~~~~~~~

Choosing between filter and QuerySet.filter()在filter(Aggregate)類與QuerySet.filter()實例方法之前選擇

?

Avoid using the filter argument with a single annotation or aggregation. It’s more efficient to use QuerySet.filter() to exclude rows. The aggregation filter argument is only useful when using two or more aggregations over the same relations with different conditionals.

避免在單個注釋annotation或集合aggregation中使用filter參數(下上面Count類的初始化函數中的filter實參)。使用QuerySet.filter()排除行會更高效。集合的filter參數只當對同一關系使用兩個或更多不同條件的集合時才有用,下面Author反向關系引用Book(同一關系)的兩個Count集合(兩個),第二個需要對Count作出過濾(不同條件),。

Author.objects.annotate(

? ? num_books=Count('book'),

? ? highly_rated_books=Count( 'book', filter=Q(book__rating__gte=7)

)

?

?

總結

以上是生活随笔為你收集整理的Django ORM查询之外键、关系的反向引用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。