Refs #20939 -- Removed the Query._forced_pk hack.

This commit is contained in:
Simon Charette 2017-04-23 01:05:51 -04:00
parent fcb5dbfec0
commit ec50937bcb
4 changed files with 11 additions and 11 deletions

View File

@ -81,7 +81,7 @@ class RelatedIn(In):
AND) AND)
return root_constraint.as_sql(compiler, connection) return root_constraint.as_sql(compiler, connection)
else: else:
if getattr(self.rhs, '_forced_pk', False): if not getattr(self.rhs, 'has_select_fields', True):
self.rhs.clear_select_clause() self.rhs.clear_select_clause()
if (getattr(self.lhs.output_field, 'primary_key', False) and if (getattr(self.lhs.output_field, 'primary_key', False) and
self.lhs.output_field.model == self.rhs.model): self.lhs.output_field.model == self.rhs.model):

View File

@ -367,6 +367,9 @@ class In(FieldGetDbPrepValueIterableMixin, BuiltinLookup):
placeholder = '(' + ', '.join(sqls) + ')' placeholder = '(' + ', '.join(sqls) + ')'
return (placeholder, sqls_params) return (placeholder, sqls_params)
else: else:
if not getattr(self.rhs, 'has_select_fields', True):
self.rhs.clear_select_clause()
self.rhs.add_fields(['pk'])
return super().process_rhs(compiler, connection) return super().process_rhs(compiler, connection)
def get_rhs_op(self, connection, rhs): def get_rhs_op(self, connection, rhs):

View File

@ -1100,15 +1100,12 @@ class QuerySet:
self._known_related_objects.setdefault(field, {}).update(objects) self._known_related_objects.setdefault(field, {}).update(objects)
def _prepare_as_filter_value(self): def _prepare_as_filter_value(self):
if self._fields is None: if self._fields and len(self._fields) > 1:
queryset = self.values('pk')
queryset.query._forced_pk = True
else:
# values() queryset can only be used as nested queries # values() queryset can only be used as nested queries
# if they are set up to select only a single field. # if they are set up to select only a single field.
if len(self._fields) > 1: if len(self._fields) > 1:
raise TypeError('Cannot use multi-field values as a filter value.') raise TypeError('Cannot use multi-field values as a filter value.')
queryset = self._clone() queryset = self._clone()
return queryset.query.as_subquery_filter(queryset._db) return queryset.query.as_subquery_filter(queryset._db)
def _add_hints(self, **hints): def _add_hints(self, **hints):

View File

@ -214,6 +214,10 @@ class Query:
self._annotations = OrderedDict() self._annotations = OrderedDict()
return self._annotations return self._annotations
@property
def has_select_fields(self):
return bool(self.select or self.annotation_select_mask or self.extra_select_mask)
def __str__(self): def __str__(self):
""" """
Return the query as a string of SQL with the parameter values Return the query as a string of SQL with the parameter values
@ -326,7 +330,6 @@ class Query:
if hasattr(obj, '_setup_query'): if hasattr(obj, '_setup_query'):
obj._setup_query() obj._setup_query()
obj.context = self.context.copy() obj.context = self.context.copy()
obj._forced_pk = getattr(self, '_forced_pk', False)
return obj return obj
def add_context(self, key, value): def add_context(self, key, value):
@ -1060,10 +1063,7 @@ class Query:
# opts would be Author's (from the author field) and value.model # opts would be Author's (from the author field) and value.model
# would be Author.objects.all() queryset's .model (Author also). # would be Author.objects.all() queryset's .model (Author also).
# The field is the related field on the lhs side. # The field is the related field on the lhs side.
# If _forced_pk isn't set, this isn't a queryset query or values() if (isinstance(value, Query) and not value.has_select_fields and
# or values_list() was specified by the developer in which case
# that choice is trusted.
if (getattr(value, '_forced_pk', False) and
not check_rel_lookup_compatibility(value.model, opts, field)): not check_rel_lookup_compatibility(value.model, opts, field)):
raise ValueError( raise ValueError(
'Cannot use QuerySet for "%s": Use a QuerySet for "%s".' % 'Cannot use QuerySet for "%s": Use a QuerySet for "%s".' %