在序列化器中使用验证响应对字段长度约束进行建模

Use*_*716 5 python django django-models django-serializer django-rest-framework

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

在发送太长的字符串时,我收到错误:

django.db.utils.DataError: value too long for type character varying(3)
Run Code Online (Sandbox Code Playgroud)

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

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

验证器.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."
Run Code Online (Sandbox Code Playgroud)

序列化器.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
Run Code Online (Sandbox Code Playgroud)

模型.py

class SeaUser(AbstractUser):
    ...
    role = models.CharField(_('Role'), max_length=3)
Run Code Online (Sandbox Code Playgroud)

但请求仍然返回错误(value too long...如上所述)。我预计错误会被序列化器捕获,并且值不会传递给模型,为什么该值会到达模型?

我对此进行了研究,所有解决方案都说将字段长度设置为 255。这并不能回答为什么模型首先要测试该值,也不能解释如果不知何故比预期值长会发生什么确实最终出现在请求中。

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

Ent*_*tin 3

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

您可以通过向序列化器添加 .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
Run Code Online (Sandbox Code Playgroud)

CustomUserValidators彻底去除。

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

def validate_user_role(value):
    return 0 < len(value) <= 3
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以将此函数放置在单独的模块中,然后在序列化器中使用:

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
Run Code Online (Sandbox Code Playgroud)

另一个更简单的解决方案是使用序列化器的 CharField 属性并执行以下操作:

class LagoonUserCreateSerializer(UserCreateSerializer):
    role = serializers.CharField(min_length=1, max_length=3)
Run Code Online (Sandbox Code Playgroud)

这将验证您的输入,而无需实现 validate_role 方法。