Opened 9 years ago
Closed 2 years ago
#26261 closed Bug (fixed)
QuerySet.exclude() crashes when referencing related_query_name of GenericRelation
Reported by: | Amir Hadi | Owned by: | gorodovoy9000 |
---|---|---|---|
Component: | contrib.contenttypes | Version: | 1.8 |
Severity: | Normal | Keywords: | GenericRelation exclude |
Cc: | steve@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Someone (Daniel H) already reported this in the Django users group: https://groups.google.com/forum/#!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. (InteractiveConsole) >>> 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() 3 >>> 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/query.py", 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/query.py", 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/query.py", 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/query.py", 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/query.py", 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/query.py", 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/query.py", 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)
Change History (12)
by , 9 years ago
Attachment: | djangogenericrelationbug.zip added |
---|
comment:1 by , 9 years ago
Type: | Uncategorized → Bug |
---|
comment:2 by , 9 years ago
This also happens when you use Q objects combined with NOT.
Insights.objects.filter(~Q(a__name='Test'))
comment:3 by , 9 years ago
Summary: | Using GenericRelation with exclude → QuerySet.exclude() crashes when referencing related_qurey_name of GenericRelation |
---|---|
Triage Stage: | Unreviewed → Accepted |
Looks like this hasn't worked since the introduction of related_query_name
in Django 1.7. Attaching a regression test.
by , 9 years ago
Attachment: | 26261-test.diff added |
---|
comment:4 by , 9 years ago
Summary: | QuerySet.exclude() crashes when referencing related_qurey_name of GenericRelation → QuerySet.exclude() crashes when referencing related_query_name of GenericRelation |
---|
comment:5 by , 8 years ago
Cc: | added |
---|
comment:6 by , 8 years ago
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 have 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.
comment:7 by , 6 years ago
Since this is not fixed yet, a workaround would be to use Conditional Expressions
from django.db import models Insights.objects.annotate( is_a_name_eq_to_test=models.Case( models.When( a__name='Test2', then=models.Value(True), ), default=models.Value(False), output_field=models.BooleanField(), ) ).filter(is_a_name_eq_to_test=False)
comment:9 by , 2 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Demo Project