Ответ
Для кастомизации логики получения одного объекта в ModelViewSet необходимо переопределить его метод retrieve в дочернем классе. Это позволяет добавить дополнительную логику, изменить данные перед отправкой или выполнить проверку прав.
Зачем это может понадобиться:
- Добавить в ответ связанные данные, которые не входят в стандартный сериализатор.
- Увеличить счетчик просмотров объекта.
- Выполнить сложную проверку прав доступа перед отдачей объекта.
Пример: Добавление дополнительного поля в ответ
from rest_framework import viewsets, status
from rest_framework.response import Response
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def retrieve(self, request, *args, **kwargs):
# 1. Получаем объект стандартным способом
instance = self.get_object()
# 2. Увеличиваем счетчик просмотров (кастомная логика)
instance.views_count += 1
instance.save()
# 3. Сериализуем данные
serializer = self.get_serializer(instance)
data = serializer.data
# 4. Добавляем в ответ дополнительную информацию
data['is_author'] = instance.author == request.user
# 5. Возвращаем кастомизированный Response
return Response(data, status=status.HTTP_200_OK)
Ключевые компоненты:
self.get_object(): Стандартный метод DRF для получения объекта поpkиз URL.self.get_serializer(instance): Получение экземпляра сериализатора для конкретного объекта.Response(data): Стандартный объект ответа DRF, который необходимо вернуть в конце.