DRF Как выполнить дополнительные операции над экземпляром

Какой из приведенных способов написания дополнительной логики является технически правильным? Пример включает изменение статуса документа. После беглого изучения похожих вопросов, я понял, что есть 3 возможности, описанные ниже. Однако, ни один ответ не описывает, какое решение используется в повседневной практике, а примеры из документации не развеивают сомнений. Пожалуйста, помогите.

Предоставление пользовательских данных сериализатору и стандартному сериализатору модели:

class PZSaveAPIView(APIView):
    @transaction.atomic
    def patch(self, request, pk, format=None):
        document = get_object_or_404(PZ, pk=pk)
        print(request.data)
        serializer = PZModelSerializer(
            document, data={'status': 'E'}, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

После сериализации объекта измените статус:

class PZSaveAPIView(APIView):
    @transaction.atomic
    def patch(self, request, pk, format=None):
        document = get_object_or_404(PZ, pk=pk)
        serializer = PZModelSerializer(
            document, data=request.data, partial=True)
        if serializer.is_valid():
            pz = serializer.save()
            pz.status = 'S'
            pz.save()
            return Response(serializer.data)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Содержите логику в сериализаторе, а представление остается базовым:

class PZUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = PZ
        fields = '__all__'
        
    def update(self, instance, validated_data):
        instance.status = 'S'
        instance.save()
        return instance

Нужно ли вообще использовать сериализатор в таких случаях? Пример:

class PZSaveAPIView(APIView):
    def patch(self, pk):
        document = get_object_or_404(PZ, pk=pk)
        document.set_status_saved()
        document.save()
        return Response('Document saved')

Если есть необходимость в проверке данных и возврате этих данных на передний план, сериализатор определенно необходим. Так что, использовать сериализатор или нет, зависит от конкретного случая, можно не использовать сериализатор, если в нем нет необходимости. Что касается того, где размещать логику - в представлениях или в сериализаторе, книги по Django рекомендуют толстый сериализатор и тонкие представления. А сам Django rest framework предоставляет update и create методы в ModelSerializer, что означает, что он предпочитает логику обновления и создания внутри сериализатора, а представлениям просто возвращать ответ.

Вернуться на верх