DRF 完整性错误:NOT NULL 约束失败:user_id

问题描述 投票:0回答:2

我不知道如何将用户对象传递给以下序列化器:

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

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

我有这样的观点:

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

还有这个型号:

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)

我的 JavaScript 请求如下所示:

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}`
  }
})

它给了我这个回溯

我应该如何将用户对象传递给请求?

提前致谢。

django rest django-models django-rest-framework django-database
2个回答
2
投票

从序列化器中删除

read_only=True

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

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

如果您设置

read_only=True
,DRF 将不会从输入源获取值,即使它存在

来自医生,

API 输出中包含只读字段,但不应该 包含在创建或更新操作期间的输入中。任何 序列化器中错误包含的“read_only”字段 输入将被忽略。

将其设置为

True
以确保序列化时使用该字段 表示,但在创建或更新实例时不使用 反序列化期间。

默认为

False


更新
您应该将

create()
ReviewSerializer
方法重写为

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',)



仅用于调试目的

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)

0
投票

只需添加这个

class ReviewSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    # new line
    user_id = serializers.IntegerField(write_only=True)

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

只读

只读字段包含在 API 输出中,但在创建或更新操作期间不应包含在输入中。序列化器输入中错误包含的任何“read_only”字段都将被忽略。

将此设置为 True 以确保在序列化表示时使用该字段,但在反序列化期间创建或更新实例时不使用该字段。

默认为False

只写

将其设置为 True 以确保在更新或创建实例时可以使用该字段,但在序列化表示时不包含该字段。

默认为False

© www.soinside.com 2019 - 2024. All rights reserved.