在DRF中的字段级别验证中获取另一个字段的值

use*_*493 9 django django-rest-framework

Field level Validation在我的序列化器中使用,我有一种情况,我需要第一个字段的值,同时验证第二个字段.我知道在object level validation我可以访问,但我的serailzer有many=True和对象级别验证我不能告诉客户端哪个迭代引起了错误.

Serailzer:

class Keys_Serializer(serializers.Serializer):
    """
    """
    key_id = serializers.IntegerField(required=True)
    key_name = serializers.CharField(required=True)
    value_id = serializers.IntegerField(required=False)

    def validate_key_id(self, value):
        """
        validate key id
        """
         *** validate key_id here ***
        return value

    def validate_value_id(self, value):
        """
        validate value_id w.r.t key_id
        """
         *** I need key_id of current iteration here so that I can validate value_id. ***
        return value
Run Code Online (Sandbox Code Playgroud)

有没有办法在value_id验证中访问key_id的值.

ils*_*005 14

不,这是不可能的.如果您需要访问多个值,则必须使用Object-level validation(请参阅文档):

class Keys_Serializer(serializers.Serializer):

    key_id = serializers.IntegerField(required=True)
    key_name = serializers.CharField(required=True)
    value_id = serializers.IntegerField(required=False)

    def validate(self, data):
        # here you can access all values
        key_id = data['key_id']
        value_id = data['value_id']
        # perform you validation
        if key_id != value_id:
            raise serializers.ValidationError("key_id must be equal to value_id")
        return data
Run Code Online (Sandbox Code Playgroud)


Sag*_*ari 13

我对 drf 的代码库进行了一些挖掘。您可以使用以下方法获取所有字段的值。这样你就可以抛出序列化错误而{'my_field':'error message}不是{'non_field_error':'error message'}

def validate_myfield(self, value):
   data = self.get_initial() # data for all the fields
   #do your validation
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望为 执行此操作ListSerializer,即 for serializer = serializer_class(many=True),则这是行不通的。您将获得空值列表。在这种情况下,您可以在函数中编写验证def validate,并避免non_field_errors序列化错误,您可以ValidationError将错误消息作为字典而不是字符串引发。

def validate(self, data):
    # do your validation
    raise serializers.ValidationError({"your_field": "error_message"})
Run Code Online (Sandbox Code Playgroud)