#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.

Reply via email to