【问题标题】:Django Rest Framework serializer is ignoring the model instance im trying to serializeDjango Rest Framework 序列化程序忽略了我试图序列化的模型实例
【发布时间】:2020-09-29 05:50:42
【问题描述】:

我正在尝试在 POST 请求上创建序列化程序的实例,但它忽略了作为第一个参数传递的模型实例

if request.method == 'POST':
        if string_pk in reviewed_user_pk:
            reviewed_user = User.objects.get(pk=user_pk)
            review = Review(author=user, reviewed_user=reviewed_user)
            serializer = CreateReviewSerializer(review, data=request.data)

我从请求中获取用户实例:

    try:
        user = request.user
    except user.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

这里的问题是ReviewSerializer忽略了具有两个用户实例(作者和review_user)的Review实例,这里是序列化器:

class CreateReviewSerializer(serializers.ModelSerializer):

    class Meta:
        model = Review
        fields = ['author', 'reviewed_user','title',  'rating', 'comment', 'date_published']

request.data 中的其他字段正在被序列化,但 Review 实例没有被序列化,是什么导致了这个问题?我从 serializer.errors 得到的错误如下:

{
    "author": [
        "This field is required."
    ],
    "reviewed_user": [
        "This field is required."
    ]
}

这是完整的功能视图:

@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def api_create_review_view(request, user_pk): #user_pk is the pk of the reviewed_user
    try:
        user = request.user
    except user.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    reviewed_user_pk = user.worked_with.split(',')
    string_pk = str(user_pk)
    data = {

    }

    if request.method == 'POST':
        if string_pk in reviewed_user_pk:
            reviewed_user = User.objects.get(pk=user_pk)
            review = Review(author=user, reviewed_user=reviewed_user)
            serializer = ReviewSerializer(review, data=request.data)

            if serializer.is_valid():
                serializer.save()

                reviews_count = reviewed_user.reviews_count
                rating = ((reviewed_user.rating * reviews_count) / (reviews_count + 1)) + ((serializer.rating) / (reviews_count + 1))

                reviews_count += 1
                reviewed_user.rating = rating
                reviewed_user.reviews_count = reviews_count
                reviewed_user.save()

                return Response(serializer.data)
            data = serializer.errors
            return Response(data)
        else:
            data = {
                'forbidden':'users have not worked together'
            }
            return Response(data=data)

这是审查模型:

class Review(models.Model):

    reviewed_user =     models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='reviewed_user')
    author =            models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='author')
    rating =            models.IntegerField(default=5)
    title =             models.CharField(max_length=50)
    comment =           models.CharField(max_length=500)
    date_published =    models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

现在我并不担心 if 语句中检查序列化程序是否有效的代码有效,我只想知道如何将 Review 的实例与两个用户实例一起传递给序列化程序,以便序列化程序有效

【问题讨论】:

    标签: django serialization django-rest-framework


    【解决方案1】:

    如果您尝试创建一个新的 Review 实例。试试这两种方法,不知道哪一种能用。

    第一种方式,更改request.data:

    from copy import deepcopy
    
    reviewed_user = User.objects.get(pk=user_pk)
    
    serializer_data = deepcopy(request.data)
    serializer_data['user'] = user
    serializer_data['reviewed_user'] = reviewed_user
    
    serializer = ReviewSerializer(serializer_data)
    if serializer.is_valid():
        serializer.save()
    

    第二种方式,只需在序列化器中设置partial=partial将序列化器更改为部分:

    reviewed_user = User.objects.get(pk=user_pk)
    review = Review(author=user, reviewed_user=reviewed_user)
    serializer = ReviewSerializer(review, data=request.data, partial=partial)
    
    if serializer.is_valid():
    

    第三种方式,在序列化器中不验证用户和review_user,保存即可, 删除序列化程序中的 'author'、'reviewed_user':

    class CreateReviewSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Review
            fields = ['title',  'rating', 'comment', 'date_published']
    
    reviewed_user = User.objects.get(pk=user_pk)
    serializer = ReviewSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save(author=user, reviewed_user=reviewed_user) # save user and reviewed_user here
    

    【讨论】:

    • 谢谢,第三个解决方案成功了!我仍然不知道为什么序列化程序忽略了 Review 实例,但我想我们永远不会知道大声笑
    猜你喜欢
    • 2020-05-23
    • 2017-06-04
    • 2015-12-16
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 2020-08-04
    相关资源
    最近更新 更多