當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python Django GenericRelation用法及代碼示例


本文介紹 django.contrib.contenttypes.fields.GenericRelation 的用法。

聲明

class GenericRelation

如果您知道最常使用的模型,您還可以添加 “reverse” 通用關係以啟用額外的 API。例如:

from django.contrib.contenttypes.fields import GenericRelation
from django.db import models

class Bookmark(models.Model):
    url = models.URLField()
    tags = GenericRelation(TaggedItem)

Bookmark 每個實例都有一個 tags 屬性,可用於檢索其關聯的 TaggedItems

>>> b = Bookmark(url='https://www.djangoproject.com/')
>>> b.save()
>>> t1 = TaggedItem(content_object=b, tag='django')
>>> t1.save()
>>> t2 = TaggedItem(content_object=b, tag='python')
>>> t2.save()
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>

您還可以使用 add()create()set() 來創建關係:

>>> t3 = TaggedItem(tag='Web development')
>>> b.tags.add(t3, bulk=False)
>>> b.tags.create(tag='Web framework')
<TaggedItem: Web framework>
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: python>, <TaggedItem: Web development>, <TaggedItem: Web framework>]>
>>> b.tags.set([t1, t3])
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: Web development>]>

remove() 調用將批量刪除指定的模型對象:

>>> b.tags.remove(t3)
>>> b.tags.all()
<QuerySet [<TaggedItem: django>]>
>>> TaggedItem.objects.all()
<QuerySet [<TaggedItem: django>]>

clear() 方法可用於批量刪除實例的所有相關對象:

>>> b.tags.clear()
>>> b.tags.all()
<QuerySet []>
>>> TaggedItem.objects.all()
<QuerySet []>

使用 related_query_name 集定義 GenericRelation 允許從相關對象進行查詢:

tags = GenericRelation(TaggedItem, related_query_name='bookmark')

這可以從 TaggedItemBookmark 進行過濾、排序和其他查詢操作:

>>> # Get all tags belonging to bookmarks containing `django` in the url
>>> TaggedItem.objects.filter(bookmark__url__contains='django')
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>

如果您不添加 related_query_name ,您可以手動執行相同類型的查找:

>>> bookmarks = Bookmark.objects.filter(url__contains='django')
>>> bookmark_type = ContentType.objects.get_for_model(Bookmark)
>>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id, object_id__in=bookmarks)
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>

正如 GenericForeignKey 接受 content-type 和 object-ID 字段的名稱作為參數一樣, GenericRelation 也是如此;如果具有通用外鍵的模型對這些字段使用非默認名稱,則在設置 GenericRelation 時必須將字段名稱傳遞給它。例如,如果上麵提到的 TaggedItem 模型使用名為 content_type_fkobject_primary_key 的字段來創建其通用外鍵,則需要像這樣定義返回它的 GenericRelation

tags = GenericRelation(
    TaggedItem,
    content_type_field='content_type_fk',
    object_id_field='object_primary_key',
)

另請注意,如果您刪除具有 GenericRelation 的對象,則具有指向它的 GenericForeignKey 的任何對象也將被刪除。在上麵的示例中,這意味著如果 Bookmark 對象被刪除,任何指向它的 TaggedItem 對象都將同時被刪除。

ForeignKey 不同, GenericForeignKey 不接受 on_delete 參數來自定義此行為;如果需要,您可以通過不使用 GenericRelation 來避免 cascade-deletion ,並且可以通過 pre_delete 信號提供替代行為。

相關用法


注:本文由純淨天空篩選整理自djangoproject.com大神的英文原創作品 django.contrib.contenttypes.fields.GenericRelation。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。