【问题标题】:DjangoRestFramework ModelSerializer: field-level validation is not workingDjangoRestFramework ModelSerializer:字段级验证不起作用
【发布时间】:2015-08-13 01:37:58
【问题描述】:

这是我的 serializers.py(我想为内置的 User 模型创建一个序列化器):

from rest_framework import serializers

from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password', 'email', )

    def validate_username(self, username):
        if not re.search(r'^\w+$', username): #checks if all the characters in username are in the regex. If they aren't, it returns None
            raise serializers.ValidationError('Username can only contain alphanumeric characters and the underscore.')
        try:
            User.objects.get(username=username)
        except ObjectDoesNotExist:
            return username
        raise serializers.ValidationError('Username is already taken.')

问题是,当我尝试使用已经存在的用户名创建用户时,它会返回以下字典:

{'username': [u'This field must be unique.']}

而不是说

{'username': [u'Username is already taken']}

我为此重新创建了 validate_username 函数(用于测试目的):

    def validate_username(self, username):
        raise serializers.ValidationError('Testing to see if an error is raised.')

并且它不会引发错误。知道为什么 DjangoRestFramework 会忽略 validate_username 函数吗?

编辑:请注意,我使用的是 ModelSerializer(在此处的教程中:http://www.django-rest-framework.org/api-guide/serializers/#validation 它仅讨论了 Serializer 的字段级验证,而不是 ModelSerializer)。请注意确定它是否有所作为。

【问题讨论】:

  • 使用非字母数字字符是否正确调用?
  • @jvc26 不。它会抛出一个错误,上面写着 {'username': [u'Enter a valid username.这个值可能只包含字母、数字和@/./+/-/_ 字符。']} 我在这里看到的更大问题是,即使我将 validate_username 函数更改为 "def validate_username(self, username): raise serializers .ValidationError('Testing to see if the error is raise.')",甚至没有引发错误,所以似乎 Django 忽略了我的 validate_username 函数(或者它只是没有传递到前端从我的 validate_username 函数引发的错误)。
  • @jvc26 我编辑了我的帖子并注意到我使用的是 ModelSerializer(不是序列化程序)。不确定它是否会有所作为。

标签: django django-models error-handling django-rest-framework django-serializer


【解决方案1】:

在序列化程序级验证之前调用字段级验证。

所以模型User 的用户名为unique=True,由于用户名已经存在,字段级验证将引发异常。 DRF 的UniqueValidator 会在字段不唯一时引发异常。

根据 DRF 源代码,

class UniqueValidator:
    """
    Validator that corresponds to `unique=True` on a model field.

    Should be applied to an individual field on the serializer.
    """
    message = _('This field must be unique.')

由于这些验证器在序列化程序级别验证之前运行,因此您的 validate_username 永远不会被调用。

【讨论】:

    【解决方案2】:

    尝试在您的序列化程序中添加以下行以使此验证器正常工作。

    class UserSerializer(serializers.ModelSerializer):
        username = serializers.CharField(max_length=32)
    
    class Meta:
        model = User
        fields = ('username', 'password', 'email', )
    

    【讨论】:

      猜你喜欢
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 2011-05-03
      • 1970-01-01
      相关资源
      最近更新 更多