#26820: Reverse join in `exclude` fails when GenericRelation is defined on an abstract model ----------------------------------------------+-------------------- Reporter: sbussetti | Owner: nobody Type: Bug | Status: new Component: Database layer (models, ORM) | Version: 1.9 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 ----------------------------------------------+-------------------- Exact same use case and setup as #20378. passing the reverse for a GenericRelation to QuerySet.filter works just fine, but for QuerySet.exclude it fails with AttributeError: 'GenericRelation' object has no attribute 'field'
{{{ AttributeError Traceback (most recent call last) <ipython-input-10-0e802368f888> in <module>() ----> 1 Comment.objects.exclude(list_set__comments_enabled=False) ./lib/python2.7/site-packages/django/db/models/manager.pyc in manager_method(self, *args, **kwargs) 120 def create_method(name, method): 121 def manager_method(self, *args, **kwargs): --> 122 return getattr(self.get_queryset(), name)(*args, **kwargs) 123 manager_method.__name__ = method.__name__ 124 manager_method.__doc__ = method.__doc__ ./lib/python2.7/site-packages/django/db/models/query.pyc in exclude(self, *args, **kwargs) 795 set. 796 """ --> 797 return self._filter_or_exclude(True, *args, **kwargs) 798 799 def _filter_or_exclude(self, negate, *args, **kwargs): ./lib/python2.7/site-packages/django/db/models/query.pyc in _filter_or_exclude(self, negate, *args, **kwargs) 804 clone = self._clone() 805 if negate: --> 806 clone.query.add_q(~Q(*args, **kwargs)) 807 else: 808 clone.query.add_q(Q(*args, **kwargs)) ./lib/python2.7/site-packages/django/db/models/sql/query.pyc in add_q(self, q_object) 1241 existing_inner = set( 1242 (a for a in self.alias_map if self.alias_map[a].join_type == INNER)) -> 1243 clause, _ = self._add_q(q_object, self.used_aliases) 1244 if clause: 1245 self.where.add(clause, AND) ./lib/python2.7/site-packages/django/db/models/sql/query.pyc in _add_q(self, q_object, used_aliases, branch_negated, current_negated, allow_joins, split_subq) 1267 child, can_reuse=used_aliases, branch_negated=branch_negated, 1268 current_negated=current_negated, connector=connector, -> 1269 allow_joins=allow_joins, split_subq=split_subq, 1270 ) 1271 joinpromoter.add_votes(needed_inner) ./lib/python2.7/site-packages/django/db/models/sql/query.pyc in build_filter(self, filter_expr, branch_negated, current_negated, can_reuse, connector, allow_joins, split_subq) 1179 except MultiJoin as e: 1180 return self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]), -> 1181 can_reuse, e.names_with_path) 1182 1183 if can_reuse is not None: ./lib/python2.7/site-packages/django/db/models/sql/query.pyc in split_exclude(self, filter_expr, prefix, can_reuse, names_with_path) 1497 # Try to have as simple as possible subquery -> trim leading joins from 1498 # the subquery. -> 1499 trimmed_prefix, contains_louter = query.trim_start(names_with_path) 1500 1501 # Add extra check to make sure the selected field will not be null ./lib/python2.7/site-packages/django/db/models/sql/query.pyc in trim_start(self, names_with_path) 1932 self.unref_alias(alias) 1933 # The path.join_field is a Rel, lets get the other side's field -> 1934 join_field = path.join_field.field 1935 # Build the filter prefix. 1936 paths_in_prefix = trimmed_paths AttributeError: 'GenericRelation' object has no attribute 'field' }}} -- Ticket URL: <https://code.djangoproject.com/ticket/26820> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/052.23dc9ef6b3c9137a7f77b59b1155df5b%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.