Получение полей из дополнительных методов менеджера с помощью django-rest-framework
У меня есть следующий пользовательский менеджер моделей в Django, который предназначен для подсчета количества связанных комментариев и добавления их в набор запросов объектов:
class PublicationManager(models.Manager):
def with_counts(self):
return self.annotate(
count_comments=Coalesce(models.Count('comment'), 0)
)
Добавление этого менеджера в модель не добавляет автоматически дополнительное поле в DRF. В своем представлении API я нашел способ получить поле count_comments
, переопределив функцию get следующим образом:
class PublicationDetails(generics.RetrieveUpdateAPIView):
queryset = Publication.objects.with_counts()
...
def get(self, request, pk):
queryset = self.get_queryset()
serializer = self.serializer_class(queryset.get(id=pk))
data = {**serializer.data}
data['count_comments'] = queryset.get(id=pk).count_comments
return Response(data)
Это работает для одного экземпляра, но когда я пытаюсь применить это к постраничному представлению списка с помощью pagination_class
, переопределение метода get, похоже, удаляет функциональность постраничного представления (т.е. я получаю список результатов вместо обычного объекта страницы с предыдущим, следующим и т.д.). Это наводит меня на мысль, что я делаю что-то не так: должен ли я вместо этого добавить дополнительное поле пользовательского менеджера в сериализатор? Я не уверен, как действовать дальше, учитывая, что я использую сериализатор модели. Должен ли я использовать базовый сериализатор?
В итоге я решил эту проблему, создав пользовательский класс пагинации и переопределив метод get_paginated_response
.
class PaginationPublication(pagination.PageNumberPagination):
def get_paginated_response(self, data):
for item in data:
publication = Publication.objects.with_counts().get(id=item['id'])
item['count_comments'] = publication.count_comments
return super().get_paginated_response(data)
Не уверен, что это самое эффективное решение, но оно работает!