Refs #27149 -- Made Subquery store Query instead of Queryset.
Subquery only uses Query.
This commit is contained in:
parent
e595a713cc
commit
96b6ad94d9
@ -998,24 +998,24 @@ class Subquery(Expression):
|
|||||||
contains_aggregate = False
|
contains_aggregate = False
|
||||||
|
|
||||||
def __init__(self, queryset, output_field=None, **extra):
|
def __init__(self, queryset, output_field=None, **extra):
|
||||||
self.queryset = queryset
|
self.query = queryset.query
|
||||||
self.extra = extra
|
self.extra = extra
|
||||||
super().__init__(output_field)
|
super().__init__(output_field)
|
||||||
|
|
||||||
def _resolve_output_field(self):
|
def _resolve_output_field(self):
|
||||||
if len(self.queryset.query.select) == 1:
|
if len(self.query.select) == 1:
|
||||||
return self.queryset.query.select[0].field
|
return self.query.select[0].field
|
||||||
return super()._resolve_output_field()
|
return super()._resolve_output_field()
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
clone = super().copy()
|
clone = super().copy()
|
||||||
clone.queryset = clone.queryset.all()
|
clone.query = clone.query.clone()
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
||||||
clone = self.copy()
|
clone = self.copy()
|
||||||
clone.is_summary = summarize
|
clone.is_summary = summarize
|
||||||
clone.queryset.query.bump_prefix(query)
|
clone.query.bump_prefix(query)
|
||||||
|
|
||||||
# Need to recursively resolve these.
|
# Need to recursively resolve these.
|
||||||
def resolve_all(child):
|
def resolve_all(child):
|
||||||
@ -1033,15 +1033,15 @@ class Subquery(Expression):
|
|||||||
# Add table alias to the parent query's aliases to prevent
|
# Add table alias to the parent query's aliases to prevent
|
||||||
# quoting.
|
# quoting.
|
||||||
if hasattr(resolved, 'alias') and resolved.alias != resolved.target.model._meta.db_table:
|
if hasattr(resolved, 'alias') and resolved.alias != resolved.target.model._meta.db_table:
|
||||||
clone.queryset.query.external_aliases.add(resolved.alias)
|
clone.query.external_aliases.add(resolved.alias)
|
||||||
return resolved
|
return resolved
|
||||||
return child
|
return child
|
||||||
|
|
||||||
resolve_all(clone.queryset.query.where)
|
resolve_all(clone.query.where)
|
||||||
|
|
||||||
for key, value in clone.queryset.query.annotations.items():
|
for key, value in clone.query.annotations.items():
|
||||||
if isinstance(value, Subquery):
|
if isinstance(value, Subquery):
|
||||||
clone.queryset.query.annotations[key] = resolve(value)
|
clone.query.annotations[key] = resolve(value)
|
||||||
|
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
@ -1049,23 +1049,23 @@ class Subquery(Expression):
|
|||||||
return [
|
return [
|
||||||
x for x in [
|
x for x in [
|
||||||
getattr(expr, 'lhs', None)
|
getattr(expr, 'lhs', None)
|
||||||
for expr in self.queryset.query.where.children
|
for expr in self.query.where.children
|
||||||
] if x
|
] if x
|
||||||
]
|
]
|
||||||
|
|
||||||
def relabeled_clone(self, change_map):
|
def relabeled_clone(self, change_map):
|
||||||
clone = self.copy()
|
clone = self.copy()
|
||||||
clone.queryset.query = clone.queryset.query.relabeled_clone(change_map)
|
clone.query = clone.query.relabeled_clone(change_map)
|
||||||
clone.queryset.query.external_aliases.update(
|
clone.query.external_aliases.update(
|
||||||
alias for alias in change_map.values()
|
alias for alias in change_map.values()
|
||||||
if alias not in clone.queryset.query.alias_map
|
if alias not in clone.query.alias_map
|
||||||
)
|
)
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def as_sql(self, compiler, connection, template=None, **extra_context):
|
def as_sql(self, compiler, connection, template=None, **extra_context):
|
||||||
connection.ops.check_expression_support(self)
|
connection.ops.check_expression_support(self)
|
||||||
template_params = {**self.extra, **extra_context}
|
template_params = {**self.extra, **extra_context}
|
||||||
template_params['subquery'], sql_params = self.queryset.query.get_compiler(connection=connection).as_sql()
|
template_params['subquery'], sql_params = self.query.get_compiler(connection=connection).as_sql()
|
||||||
|
|
||||||
template = template or template_params.get('template', self.template)
|
template = template or template_params.get('template', self.template)
|
||||||
sql = template % template_params
|
sql = template % template_params
|
||||||
@ -1092,18 +1092,17 @@ class Exists(Subquery):
|
|||||||
template = 'EXISTS(%(subquery)s)'
|
template = 'EXISTS(%(subquery)s)'
|
||||||
output_field = fields.BooleanField()
|
output_field = fields.BooleanField()
|
||||||
|
|
||||||
def __init__(self, *args, negated=False, **kwargs):
|
def __init__(self, queryset, negated=False, **kwargs):
|
||||||
self.negated = negated
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def __invert__(self):
|
|
||||||
return type(self)(self.queryset, negated=(not self.negated), **self.extra)
|
|
||||||
|
|
||||||
def resolve_expression(self, query=None, *args, **kwargs):
|
|
||||||
# As a performance optimization, remove ordering since EXISTS doesn't
|
# As a performance optimization, remove ordering since EXISTS doesn't
|
||||||
# care about it, just whether or not a row matches.
|
# care about it, just whether or not a row matches.
|
||||||
self.queryset = self.queryset.order_by()
|
queryset = queryset.order_by()
|
||||||
return super().resolve_expression(query, *args, **kwargs)
|
self.negated = negated
|
||||||
|
super().__init__(queryset, **kwargs)
|
||||||
|
|
||||||
|
def __invert__(self):
|
||||||
|
clone = self.copy()
|
||||||
|
clone.negated = not self.negated
|
||||||
|
return clone
|
||||||
|
|
||||||
def as_sql(self, compiler, connection, template=None, **extra_context):
|
def as_sql(self, compiler, connection, template=None, **extra_context):
|
||||||
sql, params = super().as_sql(compiler, connection, template, **extra_context)
|
sql, params = super().as_sql(compiler, connection, template, **extra_context)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user