Django Rest Framework 自定义验证错误

Django Rest Framework custom validation errors

我正在尝试为帐户模型自定义 DRF (3.x) 的默认验证错误。 我的目标是编写验证函数以发回自定义错误消息。

我试过以下方法:

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)

    class Meta:
        model = Account
        fields = ('id', 'email', 'password',)

    def validate_password(self, value):
        """
        Validate Password.
        """
        if not value:
            raise serializers.ValidationError("Password cannot be empty!")
        elif len(value) < 5:
            raise serializers.ValidationError("Password to short...")
        return value

长度验证工作正常,但从未抛出 'password is empty' 验证,因为之前抛出默认错误('password',[u'This field may not be blank.']) .

是否有任何选项可以禁用默认错误或强制首先通过我的自定义函数进行验证?

感谢帮助!

找到解决方案:

我必须使用 to_internal_value 函数验证值,因为验证是按特定顺序 运行 (感谢 Kevin Brown): order of validation

现在我改进后的代码如下:

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)

    class Meta:
        model = Account
        fields = ('id', 'email', 'password',)

    def to_internal_value(self, data):
        password = data.get('password')
        """
        Validate Password.
        """
        if not password:
            raise serializers.ValidationError({'password': 'Password cannot be empty!'})
        elif len(password) < 5:
            raise serializers.ValidationError({'password': 'Password to short...'})

        return {
            'password': password
        }

我希望这个 post 对某些人有用:)

您可以通过在初始化字段时设置 the error_messages argument 来覆盖每个字段的验证错误。您需要传递一个字典,键为错误消息名称,值为错误消息的自定义文本。

在您的情况下,您希望实现两条错误消息:required and min_length. You may also need to override blank,这会触发您当前的错误,除非您在该字段上设置 allow_blank=True

因此,通过这些更改,您的序列化器将变成

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(
        write_only=True,
        required=False,
        min_length=5,
        error_messages={
            "blank": "Password cannot be empty.",
            "min_length": "Password too short.",
        },
    )

    class Meta:
        model = Account
        fields = ('id', 'email', 'password', )

我已将密码字段中的 len 替换为 the min_length argument

这会将您的所有验证卸载到 Django REST 框架,这将使将来的升级更加容易。如果您需要额外的自定义验证,您仍然可以覆盖 validate_password,但现在我已将其删除,因为它是空的。