Opened 4 years ago

Last modified 2 years ago

#26261 new Bug

QuerySet.exclude() crashes when referencing related_query_name of GenericRelation

Reported by: Amir Hadi Owned by: nobody
Component: contrib.contenttypes Version: 1.8
Severity: Normal Keywords: GenericRelation exclude
Cc: steve@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Someone (Daniel H) already reported this in the Django users group:!msg/django-users/vQcipOhI7N0/4plhTAJ7AAAJ

What we are experiencing is that when you use GenericForeignKey and GenericRelation, you can't use exclude on the QuerySet.

Here is our setup:

from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models

class Insights(models.Model):
    object_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    parent_object = GenericForeignKey()
    first_field = models.IntegerField()
    second_field = models.IntegerField()

class ModelA(models.Model):
    name = models.CharField(max_length=40)

    insights = GenericRelation('Insights', related_query_name='a')

class ModelB(models.Model):
    title = models.CharField(max_length=40)

    insights = GenericRelation('Insights', related_query_name='b')

and here is how to reproduce this bug:

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from app.models import *
>>> a = ModelA.objects.create(name='Test')
>>> a = ModelA.objects.create(name='Test2')
>>> b = ModelB.objects.create(title='B Test')
>>> i = Insights.objects.create(parent_object=a, first_field=1, second_field=2)
>>> i = Insights.objects.create(parent_object=a, first_field=1, second_field=2)
>>> i = Insights.objects.create(parent_object=b, first_field=1, second_field=2)
>>> Insights.objects.count()
>>> i = Insights.objects.filter(a__name='Test2')
>>> i
[<Insights: Insights object>]
>>> i = Insights.objects.filter(a__name='Test2').exclude(a__name='Test')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/", line 797, in exclude
    return self._filter_or_exclude(True, *args, **kwargs)
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/", line 806, in _filter_or_exclude
    clone.query.add_q(~Q(*args, **kwargs))
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/sql/", line 1243, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/sql/", line 1269, in _add_q
    allow_joins=allow_joins, split_subq=split_subq,
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/sql/", line 1181, in build_filter
    can_reuse, e.names_with_path)
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/sql/", line 1499, in split_exclude
    trimmed_prefix, contains_louter = query.trim_start(names_with_path)
  File "/Users/ahadi/.virtualenvs/django/lib/python3.4/site-packages/django/db/models/sql/", line 1934, in trim_start
    join_field = path.join_field.field
AttributeError: 'GenericRelation' object has no attribute 'field'

We have the problem with Django version 1.8.9, but also reproduced it with Django 1.9.2.

A demo project is attached.

Attachments (2) (18.9 KB) - added by Amir Hadi 4 years ago.
Demo Project
26261-test.diff (738 bytes) - added by Tim Graham 4 years ago.

Download all attachments as: .zip

Change History (9)

Changed 4 years ago by Amir Hadi

Demo Project

comment:1 Changed 4 years ago by Amir Hadi

Type: UncategorizedBug

comment:2 Changed 4 years ago by Amir Hadi

This also happens when you use Q objects combined with NOT.


comment:3 Changed 4 years ago by Tim Graham

Summary: Using GenericRelation with excludeQuerySet.exclude() crashes when referencing related_qurey_name of GenericRelation
Triage Stage: UnreviewedAccepted

Looks like this hasn't worked since the introduction of related_query_name in Django 1.7. Attaching a regression test.

Changed 4 years ago by Tim Graham

Attachment: 26261-test.diff added

comment:4 Changed 4 years ago by Tim Graham

Summary: QuerySet.exclude() crashes when referencing related_qurey_name of GenericRelationQuerySet.exclude() crashes when referencing related_query_name of GenericRelation

comment:5 Changed 4 years ago by Steve Bussetti

Cc: steve@… added

comment:6 Changed 3 years ago by Collederas

I'm looking into this issue and I have noticed that, referring to the regression test case that have been attached, when excluding on a TaggedItem for animal__common_name the PathInfo generated by the names_to_path method has the m2m attribute set to True. Is this correct behaviour or is this the source of the issue? Would love to know more to move towards a patch.

Last edited 3 years ago by Collederas (previous) (diff)

comment:7 Changed 2 years ago by Todor Velichkov

Since this is not fixed yet, a workaround would be to use Conditional Expressions

from django.db import models
Note: See TracTickets for help on using tickets.
Back to Top