Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between .post() , .create() and perform_create() in views.py and .create() in serializers.py

I'm confused with .post() and .create() and perform_create() in views.py and .create() in serializers.py
seems like .create() in serializers.py get the validated_data, so it can not check serializer.is_valid

Here is the serializers.py:

class PostListSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = [
            'title',
            'content',
            'publish',
        ]

    def create(self, validated_data):
        print("-------------------")
        print("5555555 - create", validated_data)
        return Post.objects.create(**validated_data)

And if my code is :

views.py

class TestPostListAPIView(ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostListSerializer

    def post(self, request, *args, **kwargs):
        serializer = PostListSerializer(data=request.data)
        if not serializer.is_valid(raise_exception=False):
            # deal with serializer.errors
            return Response({'[post]custome error 1 !!!!!!!!!'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            print("[post]- serializer.validated_data ", serializer.validated_data)
            serializer.save()
        return Response({'[post]Create success'}, status=status.HTTP_201_CREATED)

the process will go .post() in views.py --> .create() in serializers.py --> Response to client

If my views.py use:

class TestPostListAPIView(ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostListSerializer

    # def post(self, request, *args, **kwargs):
    #     serializer = PostListSerializer(data=request.data)
    #     if not serializer.is_valid(raise_exception=False):
    #         # deal with serializer.errors
    #         return Response({'[post]custome error 1 !!!!!!!!!'}, status=status.HTTP_400_BAD_REQUEST)
    #     else:
    #         print("[post]- serializer.validated_data ", serializer.validated_data)
    #         serializer.save()
    #     return Response({'[post]Create success'}, status=status.HTTP_201_CREATED)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        print("44444-1 perform_create ", serializer)
        if not serializer.is_valid(raise_exception=False):
            print("44444-3 serializer.is_valid() ", serializer.is_valid())
            return Response({'custome error!!!!!!!!!'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            print("44444-7 serializer.validated_data ", serializer.validated_data)
        self.perform_create(serializer)
        return Response({ 'Create success'}, status=status.HTTP_201_CREATED)

    def perform_create(self, serializer):
        print("1111-1 perform_create ", serializer)
        if not serializer.is_valid(raise_exception=False):
            print("1111-3 serializer.is_valid() ", serializer.is_valid())
            return Response({'custome error!!!!!!!!!'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            print("1111-7 serializer.validated_data ", serializer.validated_data)
        user = User.objects.filter(id=8)
        serializer.save(user=user.first())
        print("1111-8 perform_create ")

the process is .create() in views.py --> .perform_create() in views.py --> .create() in serializers.py --> Response to client

Both can work!
And I found if I post invalid data, the process will not go to .perform_create() part even I comment the .create() part, so seems like .perform_create() can not check serializer.is_valid(),neither

So What's the difference between .post() and .create() in views.py , should I just use .post() or should I use .create() plus .perform_create()
I want to know because I have to use custome response message like {'custome error!!!!!!!!!'} , but I'm confused with their effect, where should I put the logic

like image 894
user2492364 Avatar asked Nov 11 '16 02:11

user2492364


1 Answers

From the docs about perform_create hook and others:

These hooks are particularly useful for setting attributes that are implicit in the request, but are not part of the request data. For instance, you might set an attribute on the object based on the request user, or based on a URL keyword argument.

like image 102
Andrey Shipilov Avatar answered Nov 15 '22 21:11

Andrey Shipilov