Opened 10 years ago

Closed 10 years ago

#22207 closed New feature (fixed)

Add `related_query_name` to GenericRelation for query operations (filter, order_by, etc.) from related model

Reported by: Gabe Jackson Owned by: nobody
Component: contrib.contenttypes Version: dev
Severity: Normal Keywords: contenttypes, generic, genericrelation, reverse
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

related_name (reverse relation) should be added to GenericRelation to allow filtering from the related model.

The following patch provides this functionality including tests and documentation:
https://github.com/gabejackson/django/compare/generic_rel_reverse?expand=1

This is particularly useful for the following use cases:

class Product(model.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

class CarProduct(model.Model):
    product = generic.GenericRelation('Product', related_name='cars')
# complex hierarchy of models accurately representing a car
# ...

class WineProduct(model.Model):
    product = generic.GenericRelation('Product', related_name='wines')
# complex hierarchy of models accurately representing wine
# ...

# Get all Cars as Products based on some specific criteria of the car, and order them by another property
>>> Product.objects.filter(cars__wheels__num_spokes=4).order_by(cars__windows__transparency)

This should also fix #16920

This is also very useful for django-filter (https://github.com/alex/django-filter) allowing to filter over GFKs when GenericRelations are defined.

Change History (4)

comment:1 by Gabe Jackson, 10 years ago

pull request is ready for checking: https://github.com/django/django/pull/2393 this WILL close #16920

comment:2 by Gabe Jackson, 10 years ago

After discussion with loic, we decided the correct approach would be to make this related_query_name instead of related_name. related_name sets the accessor on instances, where related_query_name sets the accessor for filters. I think it doesn't make sense to provide reverse accessors on the related model of a GenericRelation since we can access the model directly by accessing the GFK field on the related model. Thus we also ensured that passing related_name will raise a FieldError, so this definitely also fixes #16920.

comment:3 by Gabe Jackson, 10 years ago

Summary: Add `related_name` to GenericRelation for query operations (filter, order_by, etc.) from related modelAdd `related_query_name` to GenericRelation for query operations (filter, order_by, etc.) from related model

comment:4 by Anssi Kääriäinen <akaariai@…>, 10 years ago

Resolution: fixed
Status: newclosed

In b77f26313cddbfde20dcf2661e9bd35458c2d1bd:

Fixed #22207 -- Added support for GenericRelation reverse lookups

GenericRelation now supports an optional related_query_name argument.
Setting related_query_name adds a relation from the related object back to
the content type for filtering, ordering and other query operations.

Thanks to Loic Bistuer for spotting a couple of important issues in
his review.

Note: See TracTickets for help on using tickets.
Back to Top