#28442: Error creating queryset with nested OuterRefs on a foreign key
-------------------------------------+-------------------------------------
               Reporter:  Abram      |          Owner:  nobody
  Booth                              |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  1.11
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Given a model like:
 {{{#!python
 class Agent(models.Model):
     agency = models.ForeignKey('Agency')
     ...
 }}}
 Trying to make a queryset for use in a nested subquery will fail
 (traceback+error below):
 {{{#!python
 q = Agent.objects.filter(agency_id=OuterRef(OuterRef('id')))
 }}}
 Tested in 1.11.1 and 1.11.3. Nested OuterRefs work fine with other types
 of fields.

 Traceback:
 {{{
 [...]/django/db/models/manager.py in manager_method(self, *args, **kwargs)
      83         def create_method(name, method):
      84             def manager_method(self, *args, **kwargs):
 ---> 85                 return getattr(self.get_queryset(), name)(*args,
 **kwargs)
      86             manager_method.__name__ = method.__name__
      87             manager_method.__doc__ = method.__doc__

 [...]/django/db/models/query.py in filter(self, *args, **kwargs)
     782         set.
     783         """
 --> 784         return self._filter_or_exclude(False, *args, **kwargs)
     785
     786     def exclude(self, *args, **kwargs):

 [...]/django/db/models/query.py in _filter_or_exclude(self, negate, *args,
 **kwargs)
     800             clone.query.add_q(~Q(*args, **kwargs))
     801         else:
 --> 802             clone.query.add_q(Q(*args, **kwargs))
     803         return clone
     804

 [...]/django/db/models/sql/query.py in add_q(self, q_object)
    1248         existing_inner = set(
    1249             (a for a in self.alias_map if
 self.alias_map[a].join_type == INNER))
 -> 1250         clause, _ = self._add_q(q_object, self.used_aliases)
    1251         if clause:
    1252             self.where.add(clause, AND)

 [...]/django/db/models/sql/query.py in _add_q(self, q_object,
 used_aliases, branch_negated, current_negated, allow_joins, split_subq)
    1274                     child, can_reuse=used_aliases,
 branch_negated=branch_negated,
    1275                     current_negated=current_negated,
 connector=connector,
 -> 1276                     allow_joins=allow_joins,
 split_subq=split_subq,
    1277                 )
    1278                 joinpromoter.add_votes(needed_inner)

 [...]/django/db/models/sql/query.py in build_filter(self, filter_expr,
 branch_negated, current_negated, can_reuse, connector, allow_joins,
 split_subq)
    1204             else:
    1205                 lhs = MultiColSource(alias, targets, sources,
 field)
 -> 1206             condition = lookup_class(lhs, value)
    1207             lookup_type = lookup_class.lookup_name
    1208         else:

 [...]/django/db/models/lookups.py in __init__(self, lhs, rhs)
      22     def __init__(self, lhs, rhs):
      23         self.lhs, self.rhs = lhs, rhs
 ---> 24         self.rhs = self.get_prep_lookup()
      25         if hasattr(self.lhs, 'get_bilateral_transforms'):
      26             bilateral_transforms =
 self.lhs.get_bilateral_transforms()

 [...]/django/db/models/fields/related_lookups.py in get_prep_lookup(self)
     110                 # as we don't get to the direct value branch
 otherwise.
     111                 target_field =
 self.lhs.output_field.get_path_info()[-1].target_fields[-1]
 --> 112                 self.rhs = target_field.get_prep_value(self.rhs)
     113
     114         return super(RelatedLookupMixin, self).get_prep_lookup()

 [...]/django/db/models/fields/__init__.py in get_prep_value(self, value)
     964         if value is None:
     965             return None
 --> 966         return int(value)
     967
     968     def contribute_to_class(self, cls, name, **kwargs):

 TypeError: int() argument must be a string, a bytes-like object or a
 number, not 'OuterRef'
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28442>
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/049.badd991e1102bd3ced0b906d9cfb9a80%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to