DestroyAPIView Django rest validation

2019-08-27 19:23发布

问题:

class DeleteLedgerCategory(DestroyAPIView):
    serializer_class = CategorySerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = Category.objects.filter(company = self.request.user.currently_activated_company, id=self.kwargs['pk'])
        return queryset

    def preform_destroy(self, instance):
        if instance.is_default == True:
            raise ValueError("Cannot delete default system category")
        return instance.delete()

In above class based view. I need to add custom validation error message. ie. if instance.is_default == True: raise error... and only allow to delete the instance if no error encounters. If any unclear question. Do comment

回答1:

Instead of just raise error you can customize response in destroy method:

from rest_framework.response import Response

class DeleteLedgerCategory(DestroyAPIView):
    serializer_class = CategorySerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = Category.objects.filter(company = self.request.user.currently_activated_company, id=self.kwargs['pk'])
        return queryset

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.is_default == True:
            return Response("Cannot delete default system category", status=status.HTTP_400_BAD_REQUEST)
        self.perform_destroy(instance)


回答2:

Try to override validate method of serializer,

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        # fields

    def validate_is_default(self, attrs):
        if attrs['is_default '] is True
            raise serializers.ValidationError("error message")
        return attrs


and your views.py will be,

from rest_framework.response import Response


class DeleteLedgerCategory(DestroyAPIView):
    serializer_class = CategorySerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = Category.objects.filter(company=self.request.user.currently_activated_company, id=self.kwargs['pk'])
        return queryset

    def preform_destroy(self, instance):
        serializer = CategorySerializer(data=self.get_queryset())
        serializer.is_valid(True)
        return instance.delete()