DRF IntegrityError: NOT NULL constraint failed: user_id

对着背影说爱祢 提交于 2019-12-25 00:36:45

问题


I can't figure out how to pass user object to the following serializer:

class ReviewSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)

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

I have this viewset:

class ReviewsViewSet(viewsets.ModelViewSet):
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer

and this model:

class Review(models.Model):
    title = models.CharField(max_length=255)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reviews')
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='reviews')
    review_text = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '{movie} review by {user}'.format(user=self.user, movie=self.movie)

My javascript request looks like this:

return axios({
  method: 'post',
  url: 'http://localhost:8000/api/reviews/',
  data: { // Using data from Vue
    title: this.review_title,
    movie: this.id,
    review_text: this.review_text,
    user: JSON.stringify(this.user)
  },
  headers: {
    'Content-Type': 'application/json',
    Authorization: `JWT ${token}`
  }
})

It gives me this traceback.

How should I pass the user object to the request?

Thanks in advance.


回答1:


Remove read_only=True from serializer

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

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

If you set read_only=True, the DRF will not takes the value from input source even if it's there

From the doc,

Read-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored.

Set this to True to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.

Defaults to False


UPDATE
You should override the create() method of ReviewSerializer as

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

    def create(self, validated_data):
        user_dict = validated_data.pop('user')
        user_obj, created = User.objects.get_or_create(**user_dict)
        return Review.objects.create(user=user_obj, **validated_data)

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



for debug purpose only

class ReviewsViewSet(viewsets.ModelViewSet):
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer

    def create(self, request, *args, **kwargs):
        print(request.data)  # print here <<<<
        return super(ReviewsViewSet, self).create(request, *args, **kwargs)


来源:https://stackoverflow.com/questions/52518289/drf-integrityerror-not-null-constraint-failed-user-id

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