Django - Неожиданное поведение с упорядочиванием по умолчанию после аннотаций
Я обнаружил довольно странный случай, когда если я устанавливаю порядок по умолчанию в модели на id
или -id
, а затем добавляю в запрос аннотации distinct, порядок по умолчанию игнорируется и вместо этого упорядочивается по id
возрастанию, независимо от того, как он установлен в модели Meta.
Однако, когда я выбираю поле, которое не является конкретным id
, в качестве упорядочивания модели по умолчанию и делаю то же самое, набор запросов упорядочивается правильно. Это похоже только на id
.
Что происходит? Я не уверен, является ли это странностью Django или странностью postgres, может быть, это потому, что это первичный ключ? Если я использую .order_by('-id')
после этого, то он упорядочивается как надо, а если упорядочивание нарушается аннотацией, то почему оно не всегда нарушается?
Пример
Версия Django: 4.1 Версия Postgres: 13.4
class OrderQuerySet(models.QuerySet):
def annotateItemCounts(self):
return self.annotate(
num_items=Count('order_items', distinct=True),
num_items_draft=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.DRAFT)),
num_items_back_order=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.BACK_ORDER)),
num_items_confirmed=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.CONFIRMED)),
num_items_in_progress=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.IN_PROGRESS)),
num_items_ready=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.READY)),
num_items_packed=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.PACKED)),
num_items_shipped=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.SHIPPED)),
num_items_completed=Count('order_items', distinct=True, filter=Q(order_items__state=OrderItem.OrderItemState.COMPLETE)),
)
class OrderManager(models.Manager):
def get_queryset(self):
return OrderQuerySet(self.model, using=self._db)
def annotateItemCounts(self):
return self.get_queryset().annotateItemCounts()
class Order(models.Model):
class Meta:
ordering = ['-id']
...