Django QuerySet无参order_by()的排序规则及作用问询
Django order_by() 无参数时的排序规则及查询影响
先看你提供的代码片段:
order.discounts.filter(voucher_id=OuterRef("pk")) .order_by() .values("voucher_id") .annotate(Sum("amount")) .values("amount__sum")
无参数 order_by() 的排序规则
调用不带任何字段的 order_by() 时,它会直接清除当前QuerySet上所有已有的排序规则——不管是模型Meta类里定义的默认排序,还是之前链式调用中添加的排序条件。此时QuerySet返回的结果顺序是数据库原生的返回顺序,这个顺序通常由数据的物理存储位置决定(不同数据库实现可能有差异,比如MySQL可能默认按主键排序,但这不是Django层面的强制保证),Django不会再主动添加任何排序逻辑。
保留该方法对查询的影响
在你这段代码里,保留空参数的 order_by() 是有实际作用的,直接关系到查询结果的正确性:
- 它会清除
Discount模型Meta类中设置的默认排序,避免这些排序字段被自动带入查询语句。 - 在
values()配合annotate()使用的场景下,如果QuerySet带有排序字段,Django会自动将这些排序字段添加到SQL的GROUP BY子句中。而空的order_by()清除了所有排序规则,就能确保GROUP BY只包含你指定的voucher_id,避免出现多余的分组字段,保证按优惠券ID汇总金额的结果是正确的。
举个实际场景:如果 Discount 模型的Meta默认排序是 -created_at,那如果不加上 order_by(),你的查询会自动把 created_at 加入 GROUP BY,导致聚合结果变成按 voucher_id 和 created_at 分组,这显然不符合你只想按优惠券ID汇总金额的需求。
内容的提问来源于stack exchange,提问作者Fidelis Maina
相关产品推荐
相关产品推荐

