#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 [email protected].
To post to this group, send email to [email protected].
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