[Django]-How are all serializer errors returned in DRF at once?

1👍

Please remove the customizations of validate method in UsernameSerializer and LoginSerializer and place this method inside UserRegistrationSerializer

from rest_framework.exceptions import ValidationError

def validate(self, data):
    errors = []
    data = super().validate(data)
    username = data.get("username")
    if self.Meta.model.objects.filter(username__iexact=username).exists():
       errors.append({"username":"Choose a different username"})

    username, password = [
            input.lower() for input in [data['username'], data['password']]
        ]
    if all(password[i] == password[i + 1] for i in range(len(password) - 1)) or username == password:
        errors.append({
            'password': "Invalid password"
        })
    
    if data['password'] != data['password2']:
        errors.append({"password2": "Password confirmation failed"})

    if errors:
        raise serializers.ValidationError(errors)
    return data

1👍

As Krishna mentioned, you should use the validate method of the UserRegistrationSerializer – it should be in the validate() method rather than validate_<param>() methods because it is a validation across fields, rather than a validation of a single field.

However Krishna’s raised error will not work using django 4.0.6 (for me, at least!) – the reason is that the errors object needs to be a dictionary with the fields as keys, not a list of dictionaries. Passing a list of dictionaries will cause the errors to be represented as non_field_errors.

Krishna’s corrected example would then be:

from rest_framework import serializers

class UserRegistrationSerializer(serializers.ModelSerializer):
    ...other specs ...
    def validate(self, data):
        errors = {}
        username = data.get("username")
        if self.Meta.model.objects.filter(username__iexact=username).exists():
           errors["username"] ="Choose a different username"

        username, password = [
            input.lower() for input in [data['username'], data['password']]
        ]
        if all(password[i] == password[i + 1] for i in range(len(password) - 1)) or username == password:
            errors['password'] = "Invalid password"
    
        if data['password'] != data['password2']:
           errors["password2"] ="Password confirmation failed"

        if errors:
            raise serializers.ValidationError(errors)
        return data

This will raise the errors correctly as individual field errors in django 4.0.6

Leave a comment