es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django: cómo incluir el campo faltante pk en el serializador al actualizar un objeto anidado?

Tengo un serializador en mi aplicación Django que está diseñado para actualizar un objeto anidado. La actualización funciona, pero me enfrento a otro problema: no puedo eliminar objetos que no están en validated_data['events] porque no tengo la identificación para comparar con mis identificaciones de instancia.

Para referencia, estos son mis modelos:

class Plan(models.Model):
    planId = models.CharField(primary_key=True, max_length=100, unique=True)
    name = models.CharField(max_length=200)

class PlanEvent(models.Model):
    plan = models.ForeignKey(Plan, on_delete=models.CASCADE)
    id = models.CharField(primary_key=True, max_length=100, unique=True, blank=False, null=False)
    done = models.BooleanField()
    title = models.CharField(max_length=100, blank=True)

Este es mi PlanEventUpdateSerializer:

class PlanEventUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlanEvent
        fields = ('done', 'title')

¿Hay alguna forma de incluir el id, para poder comparar las identificaciones así en mi método de actualización?

class PlanUpdateSerializer(serializers.ModelSerializer):
    events = PlanEventUpdateSerializer(many=True)
    class Meta:
        model = Plan
        fields  = ('name',)
    ....

    def update(self, instance, validated_data):
        events_validated_data = validated_data.pop('events')
        events = (instance.events.all())
        events = list(events)
        event_ids = [item['id'] for item in events_validated_data]
        for event in events:
            if event.id not in event_ids:
                event.delete()
Tags:  ,

Answer

  1. Avatar for davy.ai

    Para incluir el campo id en PlanEventUpdateSerializer para poder compararlo en el método update, puedes agregarlo a la lista de fields en la clase Meta del serializer:

    class PlanEventUpdateSerializer(serializers.ModelSerializer):
        class Meta:
            model = PlanEvent
            fields = ('id', 'done', 'title')
    

    Esto incluirá el campo id en los datos serializados para PlanEvent. Luego, en el método update de PlanUpdateSerializer, puedes comparar el id de cada instancia de PlanEvent con los valores de id en event_ids.

    class PlanUpdateSerializer(serializers.ModelSerializer):
        events = PlanEventUpdateSerializer(many=True)
    
        class Meta:
            model = Plan
            fields = ('name',)
    
        def update(self, instance, validated_data):
            events_validated_data = validated_data.pop('events')
            events = instance.events.all()
    
            # Crear una lista de IDs de evento a partir de los datos validados
            event_ids = [item['id'] for item in events_validated_data]
    
            # Eliminar cualquier evento que no esté en los datos validados
            for event in events:
                if event.id not in event_ids:
                    event.delete()
    
            # Realizar la actualización en cada evento en los datos validados
            for data in events_validated_data:
                event = PlanEvent.objects.get(id=data['id'])
                # Actualizar campos según sea necesario
                event.done = data['done']
                event.title = data['title']
                event.save()
    
            # Por último, actualizar la instancia de Plan y devolverla
            instance.name = validated_data.get('name', instance.name)
            instance.save()
            return instance
    

    Ten en cuenta que deberás ajustar PlanEventUpdateSerializer y PlanUpdateSerializer según tus necesidades específicas y asegurarte de realizar una validación adecuada y manejo de errores.

Comments are closed.