¿Cómo se devuelven todos los errores del serializador de DRF de una vez?
Estoy probando la elevación de múltiples errores de validación en (UserRegistrationSerializer). Sin embargo, DRF solo devuelve el primer error que se produce: {‘username’: [ErrorDetail(string=’Choose a different username’, code=’invalid’)]}
Espero: {‘username’: [ErrorDetail(string=’Choose a different username’, code=’invalid’)], ‘password2′: [ErrorDetail(string=’Password confirmation failed’, code=’invalid’)]}
¿Cómo se pueden tener en cuenta múltiples errores una vez que se ha validado un serializador como en el ejemplo de la documentación? https://www.django-rest-framework.org/api-guide/serializers/#validation
class TestRegisterationSerializer__002(TestCase):
'''Verify that the registeration process fails with respect
to selecting an unavailable username and password confirmation'''
@classmethod
def setUpTestData(cls):
User.objects.create_user(username="Python")
cls.data = {
'username': "Python",
'password': "#secret#",
'password2': "Secret"
}
cls.error_messages = [
"Choose a different username", "Password confirmation failed"
]
cls.serializer = UserRegisterationSerializer(data=cls.data)
def test_user_registeration_invalid_confirmation(self):
self.serializer.is_valid()
print(self.serializer.errors)
import re
from django.contrib.auth.models import User
from rest_framework import serializers
class UsernameSerializer(serializers.ModelSerializer):
username = serializers.SlugField(min_length=4, max_length=12)
def validate_username(self, value):
try:
self.Meta.model.objects.get(username__iexact=value)
except self.Meta.model.DoesNotExist:
return value
raise serializers.ValidationError("Choose a different username")
class Meta:
fields = ['username', ]
model = User
class LoginSerializer(UsernameSerializer):
password = serializers.RegexField(
r"[0-9A-Za-z]+", min_length=5, max_length=8
)
def validate(self, data):
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:
raise serializers.ValidationError({
'password': "Invalid password"
})
return data
class Meta:
fields = ['username', 'password', ]
model = User
class UserRegistrationSerializer(LoginSerializer):
password2 = serializers.RegexField(
r"[0-9A-Za-z]+", min_length=5, max_length=8, write_only=True
)
def validate(self, data):
data = super().validate(data)
if data['password'] != data['password2']:
raise serializers.ValidationError({"password2": "Password confirmation failed"})
return data
class Meta:
model = User
fields = ['username', 'password', 'password2']
davy.ai
Para tener en cuenta todos los errores de validación en
UserRegistrationSerializer
, podemos usar el métodois_valid()
provisto por DRF, y luego acceder al diccionarioerrors
para obtener todos los errores de validación del serializador.En el ejemplo dado, podemos modificar el caso de prueba de la siguiente manera:
Aquí, primero verificamos si el serializador es válido usando
is_valid()
. Si no es válido, verificamos el diccionarioerrors
para verificar si contiene todos los errores de validación esperados.Creamos un diccionario
expected_errors
con las claves como los nombres de campo y los valores como listas de instanciasserializers.ValidationError
con los errores de validación esperados. Luego comparamos este diccionario con el diccionarioerrors
devuelto por el serializador para asegurarnos de que se tengan en cuenta todos los errores de validación.Con esta modificación, deberíamos obtener la salida esperada de: