【问题标题】:Rest Framework Serializer Field Read-Only not workingRest Framework序列化器字段只读不起作用
【发布时间】:2016-11-24 00:06:57
【问题描述】:

我遇到了一个只读属性未按预期运行的问题。我查看了this question 和其他资源以尝试解决问题,但无济于事。

端点用于保存和列出用户收藏。用户可以收藏多种对象类型,因此我使用内容类型框架。

# serializers.py
class FavouriteSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    type = serializers.CharField(source='content_type', read_only=True)
    object = FavouriteObjectRelatedField(read_only=True)
    content_type = serializers.CharField(write_only=True)
    object_id = serializers.IntegerField(write_only=True)

    def create(self, validated_data, *args, **kwargs):
        content_object = Favourites.objects.get_content_object(validated_data.get('object_id'),
                                                               validated_data.get('content_type'))
        user = kwargs.get('user')
        return Favourites.objects.create_favourite(content_object, user)

    class Meta:
        model = Favourites
        fields = ('type', 'object','user','content_type','object_id')

这是根据对象类型动态序列化对象所需的FavouriteObjectRelatedField 序列化程序。

# serializers.py
class FavouriteObjectRelatedField(serializers.RelatedField):
    """
    A custom serializer to use for favourited objects.
    """
    def to_representation(self, value):
        """
        Serialize favourited objects using their respective serializer
        """
        if isinstance(value, Track):
            track = TrackBuilder(value).get_info()
            serializer = TrackSerializer(track, context=self.context, read_only=True)

        elif isinstance(value, News):
            serializer = NewsSerializer(value, context=self.context, read_only=True)

        else:
            raise Exception("Unexpected type of favourited object")

        return serializer.data

还有景色。我重写了 perform_create 方法,以便添加从 url 参数检索的用户实例。

#views.py
class UserFavouritesList(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
    serializer_class = FavouriteSerializer

    def get_user(self):
        user_id = self.kwargs.get('user_id')
        try:
            return get_user_model().objects.get(pk=user_id)
        except get_user_model().DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

    def perform_create(self, serializer):
        serializer.save(user=self.get_user())

    def get_queryset(self):
        return Favourites.objects.user_favourites(self.get_user())

我总是收到 user field required 错误。但是,如果我删除了user 字段,这个错误显然就消失了。有趣的是,如果我将user 字段重命名为owner,我仍然会收到与指定为user 的字段名称相同的错误。此处出错:

{
    "user": [
        "This field is required."
    ]
}

更新 1

与其中一个答案一样,我已经尝试设置required=True,但它没有效果。

删除read_only=True 不是一个选项,因为用户实例不应从此端点编辑。

更新 2

另一个有趣的发展:如果我删除 type 字段,它会按预期工作。奇怪但以某种方式访问​​content_type 字段肯定会对验证产生影响。

【问题讨论】:

    标签: django serialization django-rest-framework


    【解决方案1】:

    尝试在其中设置required=False,而不是read_only=True

    user = UserSerializer(required=False)
    

    【讨论】:

    • 对不起,应该说。我已经尝试过了,它没有任何效果。删除read_only 也不是一个选项,因为我不希望编辑用户实例
    • @JacobWindsor 你还在用这个得到user field is required?你能发布堆栈跟踪吗?
    • 是的,我得到了完全相同的错误。可能是一个愚蠢的问题,但有没有一种简单的方法可以在 DRF 中获取堆栈跟踪?
    • 我遇到了需要 StringRelatedField 的问题。添加 read_only=True 和 required=False 让我再次运行,虽然我不太明白为什么需要两者。
    猜你喜欢
    • 2016-11-14
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2021-03-06
    • 2015-02-27
    • 2023-03-24
    • 2023-03-18
    相关资源
    最近更新 更多