根据请求中给出的值将序列化器中的字段更改为必填字段

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

我有一个 API 端点(在这个简化的示例中)创建一个“Stuff”对象,它具有仅根据其他字段之一的值才需要的字段。

作为一个粗略的示例,以下请求是有效的:

{
"type": "A"
"name": "Steve"
"Afield1": "hello"
"Afield2": "goodbye"
}

{
"type": "B"
"name": "Paul"
}

以下则不是,因为当

Afield1
= A
 时,
Afield2
type

应该是必填字段
{
"type": "A"
"name": "Steve"
}

它应该返回此错误:

{
    "Afield1": [
        "This field is required."
    ]
    "Afield2": [
        "This field is required."
    ]
}

这是 Django Rest Framework 中缺少字段的标准错误。具体来说,错误字典是在

to_internal_values()
文件中的
serializer.py
中构建的。

但是,序列化程序必须将这些字段定义为

required=False
,因为为了使类型“B”请求有效,类型“A”的字段必须是可选的。

因此,序列化器看起来像这样:

class StuffSerializer(serializers.ModelSerializer):
    Afield1 = serializers.CharField(required=False)
    Afield2 = serializers.CharField(required=False)

我正在寻找一种在发出请求后有条件地将 required 更改为 True 的方法。我尝试从序列化器访问 Field 上的

required
属性,但它似乎对实际 Field 对象没有生效。

class StuffSerializer():

    def create(self, validated_stuff_data) -> Stuff:
            for field in ["Afield1","Afield2"]:
                if field not in validated_stuff_data:
                    # This gets the Field object for the missing field,
                    # and sets it to be required. This does NOT work
                    # because the change is not reflected on the field
                    # that gets validated after this loop
                    missing_field = self.get_fields()[field]
                    missing_field.required = True
            # This calls validation for serializer
            self.is_valid(raise_exception=True)

再次强调,我不想提出自己的自定义验证错误,而是想利用 DRF 中现有的验证逻辑。

validation django-rest-framework django-serializer
1个回答
0
投票

可以使用序列化器中的 validate 方法来完成。

from rest_framework import serializers

class StuffSerializer(serializers.ModelSerializer):
    Afield1 = serializers.CharField(required=False)
    Afield2 = serializers.CharField(required=False)

    def validate(self, attrs: dict) -> dict:
        type = attrs.get("type", None)
        field_1 = attrs.get("field_1", None)
        field_2 = attrs.get("field_2", None)

        # your condition
        if type == "A":
            if field_1 is None and field_2 is None:
                raise serializers.ValidationError("Both `field_1` and `field_2` are required")
        
        return attrs

如果

validate
方法引发错误,错误将采用以下格式

{
    "non_field_errors": [
        "Both `field_1` and `field_2` are required"
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.