Pardon me, I'm developing an app using Django REST Framework and when I try to update an user this happen
It throw me this error:
centros = validated_data.pop('centros')
KeyError: 'centros'
I'll share my code:
This is my model
class Usuario(AbstractBaseUser):
organizacion = models.CharField(verbose_name='Organización', blank=True, null=True, max_length=250)
departamento = models.CharField(verbose_name='Departamento', blank=True, null=True, max_length=250)
centros = models.ManyToManyField(Centro, verbose_name='Centro o Unidad', blank=True, related_name='centros_usuario')
telefono = models.CharField(max_length=100, verbose_name='Teléfono', blank=True, null=True)
rut = models.CharField(max_length=100, verbose_name='RUT', blank=True, null=True)
profesion = models.CharField(max_length=150, verbose_name='Profesión', blank=True, null=True)
cargo = models.CharField(max_length=150, verbose_name='Cargo', blank=True, null=True)
nacionalidad = models.CharField(max_length=100, verbose_name='Nacionalidad', blank=True, null=True)
sexo = models.CharField(max_length=10, choices=SEXO_CHOICES ,verbose_name='Sexo', blank=True, null=True)
fecha_nacimiento = models.DateField(auto_now=False, auto_now_add=False,verbose_name='Fecha de nacimiento', blank=True, null=True)
imagen_perfil = models.ImageField(upload_to='perfil/', verbose_name='Imágen de Perfil', max_length=255, blank=True, null=True)
cv = models.FileField(verbose_name='CV', upload_to='cv_usuarios/', blank=True, null=True)
direccion = models.CharField(max_length=250, blank=True, null=True, verbose_name='Dirección')
perfil = models.PositiveSmallIntegerField(
null=False,
blank=False,
default=2,
choices=PERFIL_CHOICES,
verbose_name='Perfil')
is_active = models.BooleanField(
verbose_name='active',
default=True,
help_text=(
'Designates whether this user shoud be treated as active. '
'Unselect this instead of deleting accounts. '
)
)
estado = models.CharField(verbose_name='Estado usuario', default='INHABILITADO', choices=ESTADO_CHOICES, max_length=13)
is_staff = models.BooleanField(
verbose_name='staff status',
default=False,
help_text=(
'Designates whether the user can log into this admin site. '
)
)
is_superuser = models.BooleanField(
verbose_name='superuser status',
default=False,
help_text=(
'Designates whether this user is a Superuser. '
)
)
terminos_y_condiciones = models.BooleanField(verbose_name='Términos y Condiciones', default=False)
linkedin = models.CharField(verbose_name='Linkedin', max_length=100, blank=True, null=True)
email = models.EmailField(max_length=250, unique=True, verbose_name='Correo')
first_name = models.CharField(max_length=250, verbose_name='Nombre')
last_name = models.CharField(max_length=250, verbose_name='Apellido', blank=True, null=True)
objects = UsuarioManager()
USERNAME_FIELD = 'email'
def __str__(self):
return self.first_name
def get_email_user(self):
return self.email.lower()
def save(self, *args, **kwargs):
self.email = self.email.lower()
return super(Usuario, self).save(*args, **kwargs)
This is the serializer class that I'm using to update the users:
class UpdateUsuarioSerializer(serializers.ModelSerializer):
email = serializers.CharField(max_length=250, required=False)
first_name = serializers.CharField(max_length=250, required=False)
class Meta:
model = Usuario
fields = ['organizacion',
'departamento',
'centros',
'telefono',
'rut',
'profesion',
'cargo',
'nacionalidad',
'sexo',
'fecha_nacimiento',
'imagen_perfil',
'cv',
'email',
'first_name',
'last_name',
'linkedin'
]
def update(self, instance, validated_data):
with transaction.atomic():
centros = validated_data.pop('centros')
instance = super(UpdateUsuarioSerializer, self).update(instance,validated_data)
instance.save()
instance.centros.clear()
for centro in centros:
instance.centros.add(Centro.objects.get(id=centro))
return instance
And this is the viewset:
class UsuarioViewSet(viewsets.ModelViewSet):
queryset = Usuario.objects.filter(is_active = True)
permission_classes = [permissions.AllowAny]
serializer_class = UsuarioSerializer
pagination_class = StandardResultsSetPagination
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = ['perfil']
search_fields = ['first_name', 'last_name', 'email', 'rut', 'telefono', 'profesion', 'cargo', 'centros__nombre']
def create(self, request):
imagen_perfil = request.data.get('imagen_perfil', None) or None
if imagen_perfil is not None:
try:
request.data['imagen_perfil'] = file64bits(imagen_perfil)
except ValueError as error:
raise serializers.ValidationError({'imagen_perfil': 'Error en formato de archivo'})
cv = request.data.get('cv', None) or None
if cv is not None:
try:
request.data['cv'] = file64bits(cv)
except ValueError as error:
raise serializers.ValidationError({'cv': 'Error en formato de archivo'})
serializer = UsuarioSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def update(self, request, pk=None):
imagen_perfil = request.data.get('imagen_perfil', None) or None
if imagen_perfil is not None:
try:
request.data['imagen_perfil'] = file64bits(imagen_perfil)
except ValueError as error:
raise serializers.ValidationError({'imagen_perfil': 'Error en formato de archivo'})
cv = request.data.get('cv', None) or None
if cv is not None:
try:
request.data['cv'] = file64bits(cv)
except ValueError as error:
raise serializers.ValidationError({'cv': 'Error en formato de archivo'})
instance = Usuario.objects.get(id=pk)
serializer = UpdateUsuarioSerializer(instance, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
If anyone know how to solve this problem, I'll be so thankful
I was searching many python and django forums but any answer could solve my problem