Как я могу сделать то же самое, используя 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"])