lr_optim
lr_optim

Reputation: 381

Django: how to include missing pk field into serializer when updating nested object?

I have a serializer in my Django app that is meant for updating a nested object. Updating works, but I'm facing another problem: I can't delete objects that are not in validated_data['events] because I don't have the id to be compared with my instance id's.

For reference, these are my Models:

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)

This is my PlanEventUpdateSerializer:

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

Is there some way to include the id, so I could compare the id's like this in my update method:

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()

Upvotes: 0

Views: 115

Answers (1)

lr_optim
lr_optim

Reputation: 381

I found a solution. I defined the id as a optional field in the serializer and then I was able to include it in the fields. Sending POST and PUT requests works now and I'm also able to delete objects when updating:

class PlanEventUpdateSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source='pk', required=False)
    class Meta:
        model = PlanEvent
        fields = ('id', 'done', 'title')

Upvotes: 1

Related Questions