【问题标题】:Django Rest Framework: how to make field required / read-only only for update actions such as PUT and PATCH?Django Rest Framework:如何为 PUT 和 PATCH 等更新操作设置必填字段/只读字段?
【发布时间】:2023-04-05 14:33:01
【问题描述】:

我有一个 Django 序列化程序,它有一个字段,只有更新操作(如 PUT 和 PATCH)才需要。但不适用于 POST 等创建操作。

我发现了类似的 SO question,但没有关于如何编写自定义验证来检测操作是用于创建、更新还是修补的线索。

同样,我想为其他一些字段启用只读(或使它们不可编辑)但仅用于更新操作。

我搜索了 django rest 框架文档,但没有此类自定义验证器的明确示例。

目前,我的解决方法是完全设置required=false,这不是最好的。

请指教。

【问题讨论】:

    标签: django serialization django-rest-framework deserialization


    【解决方案1】:

    您可以覆盖serializerget_fields 方法,然后您可以更改该字段的值

    class SomeDataSerializer(serializers.ModelSerializer):
        some_field = serializers.CharField(max_length=100)
    
        def get_fields(self, *args, **kwargs):
            fields = super(SomeDataSerializer, self).get_fields(*args, **kwargs)
            request = self.context.get('request', None)
            if request and getattr(request, 'method', None) == "POST":
                fields['some_field'].required = False
            return fields
    

    【讨论】:

    • 您的代码不太正确。我为适合我的内容编辑了它。
    • 在上下文中有请求总是好的,默认情况下drf的所有通用视图都有这个,如果你做序列化,那么它应该通过
    • 由于某种原因,我不得不使用这种提取请求的方式。然后它工作。不知道为什么。
    • 你必须在序列化对象创建时传递请求,在视图中
    【解决方案2】:

    在这种情况下,我所做的就是拥有一个完全不同的序列化程序,它继承自基本序列化程序并覆盖相关字段。所以在你的情况下,这样的方法应该有效:

    class CreateSerializer(serializers.Serializers):
        field = serializers.CharField(max_length=100)
    
    class UpdateSerializer(CreateSerializer):
        field = serializers.CharField(max_length=100, required=False)
    

    在你看来,返回相关的序列化器:

    def get_serializer_class(self):
        if self.request.action == "POST":
            return CreateSerializer
        elif self.request.action in ["PUT", "PATCH"]:
            return UpdateSerializer
    

    我认为这是一个很好的方法,因为您将来可能需要根据请求方法添加额外的逻辑。它也比猴子修补字段的required 属性更具可读性。

    【讨论】:

    • 谢谢。但这给我带来了很多重复的代码。无论如何,我已经解决了。谢谢你
    • 这实际上是一个很好的答案。如前所述,不会有“重复代码”,因为共享的任何内容都会进入基础。
    • 同意,Saad 的回答是更好的选择。
    • 很好的答案,谢谢。在当前 Django (3.0.x) 版本上应该是 self.request.method 而不是 self.request.action
    • 这是实现这一目标的一种更简洁的方法! +1
    猜你喜欢
    • 2013-10-27
    • 2017-08-29
    • 2016-09-18
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2018-04-15
    • 2013-11-12
    相关资源
    最近更新 更多