DjangoRestFramework ModelSerializer:字段级验证不起作用

时间:2015-05-30 04:26:53

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

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

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讨论字段级验证)。请注意确定它是否有所作为。

2 个答案:

答案 0 :(得分:4)

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

因此,将用户名为unique=True的模型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.') 可以提高异常。

根据DRF源代码,

validate_username

由于这些验证程序在序列化程序级别验证之前运行,因此永远不会调用{{1}}。

答案 1 :(得分:1)

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

class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=32)

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