【问题标题】:Model field length constraint with validation response in serializer序列化程序中具有验证响应的模型字段长度约束
【发布时间】:2019-02-25 14:26:27
【问题描述】:

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

在发送一个太长的字符串时,我得到了错误:

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

在我的模型中,我将字符字段的最大长度定义为 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."

序列化器.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)

但是请求仍然返回错误(value too long... 同上)。我预计错误会在序列化程序中被捕获并且值没有传递给模型,为什么值会一直到达模型?

我对此进行了研究,所有solutions 都说将字段长度设为 255。这并不能解释为什么模型首先会测试该值,也不能解释如果以某种方式发生了什么请求中确实会出现比预期更长的值。

对此的任何帮助表示赞赏。

【问题讨论】:

  • 这确实是次要的,但它是 Django 的 REST 框架,它不是“Django 的 REST 框架”。 Django 项目不拥有或控制 REST 框架。

标签: python django django-models django-rest-framework django-serializer


【解决方案1】:

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

您可以通过将 .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 方法的情况下验证您的输入。

【讨论】:

  • 感谢帮助,这不是问题,但我必须在多个请求中验证角色字段,这就是我使用自定义类的原因,这不是很好的做法吗? (感谢输入)
  • 是的,确实如此。您可以创建实用程序函数来验证输入并在此 validate_role 方法中调用它,然后您可以在需要的任何地方使用它。这将是一种可能的方法。
  • 您想添加一个在这种情况下如何使用实用函数的示例吗?
  • 按要求更新了答案。但请考虑我回答中的最后一种方法 - 这似乎是最简单和最简单的(除非您打算进行一些更复杂的验证)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 2019-08-28
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多