0
votes

I'm using DRF 3.2.3 and running into this problem. I have this serializer that's used to create users (web app uses a custom user model):

class CreateGRUserSerializer(serializers.ModelSerializer):
    confirm_password = serializers.CharField(max_length=128, allow_blank=False, 
            write_only=True, style={'input_type': 'password'})

    def validate(self, data):
        if data['password'] != data['confirm_password']:
            raise serializers.ValidationError({'password': "Passwords do not match", 'confirm_password': "Passwords do not match"})
        return data

    class Meta:
        model = GRUser
        fields = ('username', 'email', 'password', 'confirm_password')
        extra_kwargs = {'password': {'write_only': True, 'style': {'input_type': 'password'}}}

    def create(self, validated_data):
        user = GRUser(
            email=validated_data['email'],
            username=validated_data['username']
        )
        user.set_password(validated_data['password'])
        user.init_activation(False)
        user.save()
        return user

Problem is, error messages that were specified in model are completely ignored. For example, email field is defined like this in the GRUser model:

email = models.EmailField(_('email address'), unique=True,
    help_text=_('Email address that acts as the primary unique identifier for the user.'),
    error_messages={
        'unique': _("A user with that email already exists."),
    })

When using browsable api, DRF even manages to get and display the help text from the model, however, when I input an already used email, instead of "A user with that email already exists", I get DRF's default "This field must be unique." message.

Is there a design reason why it happens? Can I somehow make DRF use error messages from the model (other than the obvious solution of violating the DRY principle and repeating their text manually in the serializer)?

2

2 Answers

1
votes

You may have to override the UniqueValidator that is already used by ModelSerializer for unique fields. The default validator, doesn't uses messages from model, as of now. This is how you would do it:

class CreateGRUserSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(validators=[
            UniqueValidator(
                queryset=GRUser.objects.all(),
                message="A user with that email already exists.",
            )]
        )

Or you can update the 'unique' key of 'error_messages' property of fields['email'] in serializer's __init__() method.

1
votes