1
0
mirror of https://github.com/django/django.git synced 2025-06-07 04:29:12 +00:00

Refs #32786 -- Made Query.clear_ordering() not to cause side effects by default.

This commit is contained in:
Hannes Ljungberg 2021-05-26 22:09:15 +02:00 committed by Mariusz Felisiak
parent 43d1ea6e2f
commit 053141d31f
3 changed files with 21 additions and 18 deletions

View File

@ -658,7 +658,7 @@ class QuerySet:
) )
obj = self._chain() obj = self._chain()
obj.query.set_limits(high=1) obj.query.set_limits(high=1)
obj.query.clear_ordering(force_empty=True) obj.query.clear_ordering(force=True)
obj.query.add_ordering(*order_by) obj.query.add_ordering(*order_by)
return obj.get() return obj.get()
@ -741,7 +741,7 @@ class QuerySet:
# Disable non-supported fields. # Disable non-supported fields.
del_query.query.select_for_update = False del_query.query.select_for_update = False
del_query.query.select_related = False del_query.query.select_related = False
del_query.query.clear_ordering(force_empty=True) del_query.query.clear_ordering(force=True)
collector = Collector(using=del_query.db) collector = Collector(using=del_query.db)
collector.collect(del_query) collector.collect(del_query)
@ -1009,7 +1009,7 @@ class QuerySet:
# Clone the query to inherit the select list and everything # Clone the query to inherit the select list and everything
clone = self._chain() clone = self._chain()
# Clear limits and ordering so they can be reapplied # Clear limits and ordering so they can be reapplied
clone.query.clear_ordering(True) clone.query.clear_ordering(force=True)
clone.query.clear_limits() clone.query.clear_limits()
clone.query.combined_queries = (self.query,) + tuple(qs.query for qs in other_qs) clone.query.combined_queries = (self.query,) + tuple(qs.query for qs in other_qs)
clone.query.combinator = combinator clone.query.combinator = combinator
@ -1166,7 +1166,7 @@ class QuerySet:
if self.query.is_sliced: if self.query.is_sliced:
raise TypeError('Cannot reorder a query once a slice has been taken.') raise TypeError('Cannot reorder a query once a slice has been taken.')
obj = self._chain() obj = self._chain()
obj.query.clear_ordering(force_empty=False) obj.query.clear_ordering(force=True, clear_default=False)
obj.query.add_ordering(*field_names) obj.query.add_ordering(*field_names)
return obj return obj

View File

@ -1609,7 +1609,7 @@ class SQLUpdateCompiler(SQLCompiler):
return return
query = self.query.chain(klass=Query) query = self.query.chain(klass=Query)
query.select_related = False query.select_related = False
query.clear_ordering(True) query.clear_ordering(force=True)
query.extra = {} query.extra = {}
query.select = [] query.select = []
query.add_fields([query.get_meta().pk.name]) query.add_fields([query.get_meta().pk.name])

View File

@ -447,11 +447,10 @@ class Query(BaseExpression):
inner_query.select_for_update = False inner_query.select_for_update = False
inner_query.select_related = False inner_query.select_related = False
inner_query.set_annotation_mask(self.annotation_select) inner_query.set_annotation_mask(self.annotation_select)
if not self.is_sliced and not self.distinct_fields: # Queries with distinct_fields need ordering and when a limit is
# Queries with distinct_fields need ordering and when a limit # applied we must take the slice from the ordered query. Otherwise
# is applied we must take the slice from the ordered query. # no need for ordering.
# Otherwise no need for ordering. inner_query.clear_ordering(force=False)
inner_query.clear_ordering(True)
if not inner_query.distinct: if not inner_query.distinct:
# If the inner query uses default select and it has some # If the inner query uses default select and it has some
# aggregate annotations, then we must make sure the inner # aggregate annotations, then we must make sure the inner
@ -491,7 +490,7 @@ class Query(BaseExpression):
self.default_cols = False self.default_cols = False
self.extra = {} self.extra = {}
outer_query.clear_ordering(True) outer_query.clear_ordering(force=True)
outer_query.clear_limits() outer_query.clear_limits()
outer_query.select_for_update = False outer_query.select_for_update = False
outer_query.select_related = False outer_query.select_related = False
@ -534,7 +533,7 @@ class Query(BaseExpression):
combined_query.exists(using, limit=limit_combined) combined_query.exists(using, limit=limit_combined)
for combined_query in q.combined_queries for combined_query in q.combined_queries
) )
q.clear_ordering(True) q.clear_ordering(force=True)
if limit: if limit:
q.set_limits(high=1) q.set_limits(high=1)
q.add_extra({'a': 1}, None, None, None, None, None) q.add_extra({'a': 1}, None, None, None, None, None)
@ -1040,7 +1039,7 @@ class Query(BaseExpression):
if (self.low_mark == 0 and self.high_mark is None and if (self.low_mark == 0 and self.high_mark is None and
not self.distinct_fields and not self.distinct_fields and
not self.select_for_update): not self.select_for_update):
clone.clear_ordering(True) clone.clear_ordering(force=True)
clone.where.resolve_expression(query, *args, **kwargs) clone.where.resolve_expression(query, *args, **kwargs)
for key, value in clone.annotations.items(): for key, value in clone.annotations.items():
resolved = value.resolve_expression(query, *args, **kwargs) resolved = value.resolve_expression(query, *args, **kwargs)
@ -1769,7 +1768,7 @@ class Query(BaseExpression):
query = Query(self.model) query = Query(self.model)
query._filtered_relations = self._filtered_relations query._filtered_relations = self._filtered_relations
query.add_filter(filter_expr) query.add_filter(filter_expr)
query.clear_ordering(True) query.clear_ordering(force=True)
# Try to have as simple as possible subquery -> trim leading joins from # Try to have as simple as possible subquery -> trim leading joins from
# the subquery. # the subquery.
trimmed_prefix, contains_louter = query.trim_start(names_with_path) trimmed_prefix, contains_louter = query.trim_start(names_with_path)
@ -1970,14 +1969,18 @@ class Query(BaseExpression):
else: else:
self.default_ordering = False self.default_ordering = False
def clear_ordering(self, force_empty): def clear_ordering(self, force=False, clear_default=True):
""" """
Remove any ordering settings. If 'force_empty' is True, there will be Remove any ordering settings if the current query allows it without
no ordering in the resulting query (not even the model's default). side effects, set 'force' to True to clear the ordering regardless.
If 'clear_default' is True, there will be no ordering in the resulting
query (not even the model's default).
""" """
if not force and (self.is_sliced or self.distinct_fields or self.select_for_update):
return
self.order_by = () self.order_by = ()
self.extra_order_by = () self.extra_order_by = ()
if force_empty: if clear_default:
self.default_ordering = False self.default_ordering = False
def set_group_by(self, allow_aliases=True): def set_group_by(self, allow_aliases=True):