Как я могу сделать то же самое, используя DRF OrderingFilter?

Я надеюсь заказать модель по DateTimeField с помощью DRF OrderingFilter. Я могу сделать это вручную, но не с помощью бэкенда DRF.

Models.py:

class DropTemplate(TimeStampedModel):
    title = models.TextField(null=True, blank=True)
    author = models.ForeignKey(Author, on_delete=models.PROTECT)

    @property
    def earliest_start_time(self) -> Union[None, str]:
        earliest_collection = (
            self.collectiontemplates.filter(drop_template_id=self.id, visible_start_time__isnull=False)
            .only("visible_start_time")
            .order_by("visible_start_time")
            .first()
        )
        if earliest_collection is None:
            return None
        else:
            return earliest_collection.visible_start_time
  

class CollectionTemplate(TimeStampedModel):
    drop_template = models.ForeignKey(
        DropTemplate, related_name="collectiontemplates", on_delete=models.PROTECT
    )
    visible_start_time = models.DateTimeField(null=True, blank=True)

У меня есть следующее ModelViewSet:

class DropTemplateViewSet(viewsets.ModelViewSet):
    serializer_class = DropTemplateSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["status"]

    def get_queryset(self):
        drop_templates = DropTemplate.objects.annotate(start_time=F("collectiontemplates__visible_start_time")).filter(author__id=self.kwargs["author_pk"]).distinct("id")
        if "ordering" in self.request.query_params:
            return drop_templates.order_by("author_droptemplate.id", f"{self.request.query_params['ordering']}")
        else:
            return drop_templates

Я использую distinct("id"), потому что этот аннотированный набор запросов содержит DropTemplates в ответе.

Как я могу добиться того же самого с помощью OrderingFilter?

Когда я пытаюсь сделать это с помощью следующего ModelViewSet:

class DropTemplateViewSet(viewsets.ModelViewSet):
    serializer_class = DropTemplateSerializer
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_fields = ["status"]
    ordering_fields = ["title", "start_time"]
    ordering = ["start_time"]

    def get_queryset(self):
        return DropTemplate.objects.annotate(start_time=F("collectiontemplates__visible_start_time")).filter(publisher__id=self.kwargs["publisher_pk"]).distinct("id")

Я получаю эту ошибку:

SELECT DISTINCT ON expressions must match initial ORDER BY expressions LINE 1: SELECT COUNT(*) FROM (SELECT DISTINCT ON ("publisher_droptem... ^ )

Решение:

DropTemplate.objects.annotate(start_time=Subquery(collection_templates.values("visible_start_time")[:1])).filter(author__id=self.kwargs["author_pk"])
Вернуться на верх