Fixed #23791 -- Corrected object type check for pk__in=qs

When the pk was a relation field, qs.filter(pk__in=qs) didn't work.

In addition, fixed Restaurant.objects.filter(place=restaurant_instance),
where place is an OneToOneField and the primary key of Restaurant.

A big thank you to Josh for review and to Tim for review and cosmetic
edits.

Thanks to Beauhurst for commissioning the work on this ticket.
This commit is contained in:
Anssi Kääriäinen 2015-06-25 18:31:07 +03:00 committed by Tim Graham
parent 736fb1838c
commit 9ed82154bd
5 changed files with 72 additions and 20 deletions

View file

@ -19,7 +19,7 @@ from django.db.models.deletion import Collector
from django.db.models.expressions import F, Date, DateTime
from django.db.models.fields import AutoField
from django.db.models.query_utils import (
Q, InvalidQuery, deferred_class_factory,
Q, InvalidQuery, check_rel_lookup_compatibility, deferred_class_factory,
)
from django.db.models.sql.constants import CURSOR
from django.utils import six, timezone
@ -1141,16 +1141,19 @@ class QuerySet(object):
"""
return self.query.has_filters()
def is_compatible_query_object_type(self, opts):
model = self.model
return (
# We trust that users of values() know what they are doing.
self._fields is not None or
# Otherwise check that models are compatible.
model == opts.concrete_model or
opts.concrete_model in model._meta.get_parent_list() or
model in opts.get_parent_list()
)
def is_compatible_query_object_type(self, opts, field):
"""
Check that using this queryset as the rhs value for a lookup is
allowed. The opts are the options of the relation's target we are
querying against. For example in .filter(author__in=Author.objects.all())
the opts would be Author's (from the author field) and self.model would
be Author.objects.all() queryset's .model (Author also). The field is
the related field on the lhs side.
"""
# We trust that users of values() know what they are doing.
if self._fields is not None:
return True
return check_rel_lookup_compatibility(self.model, opts, field)
is_compatible_query_object_type.queryset_only = True