2π
To perform validation in the serializers, we can define a function validate_username()
which will validate the username and another function validate()
which validates password1
and password2
.
Custom Field-level validation:
We need to validate the username
, we can add a function validate_username()
to our serializers.
To specify custom field-level validation, we need to add .validate_<field_name>
methods to our Serializer subclass. These are similar to the .clean_<field_name>
methods on Django forms.
These methods take a single argument, which is the field value that
requires validation.Your
validate_<field_name>
methods should return the validated value
or raise aserializers.ValidationError
.
Object-level validation:
To do any other validation that requires access to multiple fields, we need to add a method called .validate()
to our Serializer subclass.
This method takes a single argument, which is a dictionary of field values. It should raise a ValidationError
if necessary, or just return the validated values.
Since in the clean_password2()
function, you are trying to access the value of password1
also, we need to do object-level validation by defining a validate()
function.
Final Code:
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
...
def validate_username(self, value):
if not re.search(r'^\w+$', value):
raise serializers.ValidationError('Username can only contain alphanumeric characters and the underscore.')
if User.objects.filter(username=value):
raise serializers.ValidationError('Username is already taken.')
return value # must return validated value
def validate(self, data):
password1 = data.get('password1')
password2 = data.get('password2')
if password1 != password2:
raise serializers.ValidationError('Passwords do not match.')
return data # must return validated values