Ticket #26434: main_logic.2.patch

File main_logic.2.patch, 2.4 KB (added by Michal Mládek, 7 months ago)
  • django/db/models/sql/query.py

    commit c8d8ce569ee25a48e11aba9bcef5dd29f352733f
    Author: Michal Mládek <osvc.04923031@gmail.com>
    Date:   Wed May 21 07:38:55 2025 +0200
    
        Related to #26434 - main logic
    
    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index 92a09c5840..1505454d3a 100644
    a b class Query(BaseExpression):  
    23032303        else:
    23042304            self.default_ordering = False
    23052305
     2306    @cached_property
     2307    def group_by_expressions(self):
     2308        """It converts group by items to expressions to be used
     2309        in ordering_needs_grouping
     2310        """
     2311        return {
     2312            group_e.name if hasattr(group_e, "name") else group_e
     2313            for group_e in self.group_by
     2314        }
     2315
     2316    def ordering_needs_grouping(self, order_by):
     2317        """It tells if order by could be removed or not
     2318        #26434 - QuerySet.count() has too aggresive strategy to remove it
     2319        """
     2320        if not self.group_by or isinstance(self.group_by, bool):
     2321            # it does not need grouping
     2322            return False
     2323        # order by can be Expression or String
     2324        order_e = order_by.expression if hasattr(order_by, "expression") else order_by
     2325        if hasattr(order_e, "contains_aggregate") and order_e.contains_aggregate:
     2326            # expression is aggregation -> does not need GROUP BY
     2327            return False
     2328        expr_name = order_e.name if hasattr(order_e, "name") else order_e
     2329        if expr_name in self.group_by_expressions:
     2330            # order by is not subset of grouping
     2331            return False
     2332        # otherwise order by expression needs to be in GROUP BY clause
     2333        return True
     2334
    23062335    def clear_ordering(self, force=False, clear_default=True):
    23072336        """
    23082337        Remove any ordering settings if the current query allows it without
    class Query(BaseExpression):  
    23142343            self.is_sliced or self.distinct_fields or self.select_for_update
    23152344        ):
    23162345            return
    2317         self.order_by = ()
     2346        order_by = []
     2347        if not force:
     2348            for item in self.order_by:
     2349                if not self.ordering_needs_grouping(item):
     2350                    continue
     2351                order_by.append(item)
     2352        self.order_by = tuple(order_by)
    23182353        self.extra_order_by = ()
    23192354        if clear_default:
    23202355            self.default_ordering = False
Back to Top