序列化程序中具有验证响应的模型字段长度约束

Model field length constraint with validation response in serializer

我正在使用序列化程序中的数据验证来验证来自 Django 的其余框架中的请求的数据。我需要在单个响应中发送所有错误消息。

发送太长的字符串时,出现错误:

django.db.utils.DataError: value too long for type character varying(3)

在我的模型中,我将字符字段的最大长度定义为 3(理论上需要的最大长度)。

我在序列化程序中添加了验证以捕获包含太多字符的请求:

validators.py

class CustomUserValidators():

    errors_to_return = {}
    def val_role(self, role):
            if len(role) > 3:
                self.errors_to_return["role_length"] = "Ensure this field has no more than 3 characters."

serializers.py

from Sea.validators import CustomUserValidators
class LagoonUserCreateSerializer(UserCreateSerializer, CustomUserValidators):
    class Meta:
        model = User
        fields = ('id', 'username', 'role',)


    def validate(self, attrs):
        self.val_role(attrs['role'])

        if len(self.errors_to_return) > 0:
            raise serializers.ValidationError(self.errors_to_return)

        return attrs

models.py

class SeaUser(AbstractUser):
    ...
    role = models.CharField(_('Role'), max_length=3)

但是请求还是returns错误(value too long...同上)。我预计错误会被序列化程序捕获并且值不会传递给模型,为什么值会到达模型?

我研究过这个,所有 solutions 都说字段长度为 255。这并没有回答为什么模型首先要测试该值,也没有解释如果以某种方式在请求中最终出现比预期值更长的值,会发生什么情况。

如有任何帮助,我们将不胜感激。

我会采用不同的方法并利用序列化程序的验证。

您可以通过向序列化程序添加 .validate_field 方法来指定自定义字段级验证。

因此您可以将以下方法添加到您的序列化器中。

def validate_role(self, value):
    if len(value) > 3:
        raise serializers.ValidationError("Ensure this field has no more than 3 characters")
    return value

并完全删除 CustomUserValidators

如评论中所述,您可以将验证移至实用函数并在需要的任何地方使用它。

def validate_user_role(value):
    return 0 < len(value) <= 3

如果你愿意,你可以把这个函数放在一个单独的模块中,然后在你的序列化程序中使用:

def validate_role(self, value):
    if not validate_user_role(value):
        raise serializers.ValidationError("Ensure this field has no more than 3 characters")
    return value

要考虑的另一个更简单的解决方案是使用序列化程序的 CharField 属性并执行此操作:

class LagoonUserCreateSerializer(UserCreateSerializer):
    role = serializers.CharField(min_length=1, max_length=3)

这将在不实施 validate_role 方法的情况下验证您的输入。