Django Rest Framework serializer create() doesn't get triggered

烂漫一生 提交于 2019-12-10 15:58:10

问题


I have the following serializer

class MyModelSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    def create(self, validated_data):
        print("TEST")
        MyModel, created = MyModel.objects.get_or_create(**validated_data)
        return MyModel

    class Meta:
        model = MyModel
        fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)

and the following viewset:

class MyModelViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

When I make an POST request to the endpoint corresponding to specified viewset, the create() method does absolutely nothing. I tried to print out in console TEST as you can see, but nothing.

Does anyone have an idea about this strange behavior?

Thanks in advace!

Edit: API call:

return axios({
  method: 'post',
  url: 'http://localhost:8000/api/mymodel/',
  data: {
     title: this.title,
     movie: this.id,
     text: this.text,
     user: this.user
}

回答1:


If you look at the implementation of POST handling in a ViewSet, you can find this :

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

Your create method is called after serializer validates the data.

The error you see (user already exists) is a result of calling serializer.is_valid from the snippet above.

Therefore, it never gets to call your create. Your craete would be called as part of self.perform_create() from this snippet above.

So this means that you are trying to create a user which already exists. So in your model you have unique username.




回答2:


It might because you have some sort of error handling in place, because the way your def create function is written will throw an error. I tested the below code and it worked for me give it a go:

class MyModelSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = MyModel
        fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)

    def create(self, validated_data):
        print("TEST")
        data = validated_data
        data, created = MyModel.objects.get_or_create(**data)
        return data

Hope this helps!




回答3:


Ok. I found an alternative. Since I only wanted the username from user object, I removed user = UserSerializer() and I added user_username = serializers.ReadOnlyField(source='user.username'):

class ReviewSerializer(serializers.ModelSerializer):
    user_username = serializers.ReadOnlyField(source='user.username')

    class Meta:
        model = Review
        fields = ('pk', 'title', 'user', 'user_username', 'movie', 'timestamp', 'review_text',)

user = UserSerializer() gave me headaches, so I got around it. I will check Entushiast Martin answer as a solution since they drove me to the actual answer. Thank you.

Solved.



来源:https://stackoverflow.com/questions/52523318/django-rest-framework-serializer-create-doesnt-get-triggered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!