class GenericRelation
-
related_query_name
-
The relation on the related object back to this object doesn’t exist by default. Setting
related_query_name
creates a relation from the related object back to this one. This allows querying and filtering from the related object.
If you know which models you’ll be using most often, you can also add a “reverse” generic relationship to enable an additional API. For example:
from django.db import models from django.contrib.contenttypes.fields import GenericRelation class Bookmark(models.Model): url = models.URLField() tags = GenericRelation(TaggedItem)
Bookmark
instances will each have a tags
attribute, which can be used to retrieve their associated 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>]>
Defining GenericRelation
with related_query_name
set allows querying from the related object:
tags = GenericRelation(TaggedItem, related_query_name='bookmarks')
This enables filtering, ordering, and other query operations on Bookmark
from TaggedItem
:
>>> # Get all tags belonging to bookmarks containing `django` in the url >>> TaggedItem.objects.filter(bookmarks__url__contains='django') <QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
Of course, if you don’t add the reverse relationship, you can do the same types of lookups manually:
>>> b = Bookmark.objects.get(url='https://www.djangoproject.com/') >>> bookmark_type = ContentType.objects.get_for_model(b) >>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id, object_id=b.id) <QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
Just as GenericForeignKey
accepts the names of the content-type and object-ID fields as arguments, so too does GenericRelation
; if the model which has the generic foreign key is using non-default names for those fields, you must pass the names of the fields when setting up a GenericRelation
to it. For example, if the TaggedItem
model referred to above used fields named content_type_fk
and object_primary_key
to create its generic foreign key, then a GenericRelation
back to it would need to be defined like so:
tags = GenericRelation( TaggedItem, content_type_field='content_type_fk', object_id_field='object_primary_key', )
Note also, that if you delete an object that has a GenericRelation
, any objects which have a GenericForeignKey
pointing at it will be deleted as well. In the example above, this means that if a Bookmark
object were deleted, any TaggedItem
objects pointing at it would be deleted at the same time.
Unlike ForeignKey
, GenericForeignKey
does not accept an on_delete
argument to customize this behavior; if desired, you can avoid the cascade-deletion simply by not using GenericRelation
, and alternate behavior can be provided via the pre_delete
signal.
Please login to continue.