当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。