Передать идентификатор объекта из вложенного сериализатора в родительский сериализатор в Django Rest Framework - PullRequest
0 голосов
/ 04 июля 2019

Я создал два сериализатора - ASerializer и BSerializer. Модель A имеет b поле «многие ко многим» относительно B. Моя цель - иметь возможность обновлять несколько вложенных B объектов при обновлении A объекта. Мои сериализаторы:

class ASerializer(WritableNestedModelSerializer):
    b = BSerializer(many=True)

    class Meta:
        model = A
        fields = '__all__'
        read_only_fields = ['id']

    def update(self, instance, validated_data):

        info = model_meta.get_field_info(instance)
        bs_data = validated_data.pop('b', None)

        for attr, value in validated_data.items():
            if attr in info.relations and info.relations[attr].to_many:
                field = getattr(instance, attr)
                field.set(value)
            else:
                setattr(instance, attr, value)

        if bs_data:
            for b_data in bs_data:
                b_serializer = BSerializer(data=b_data)
                if b_serializer.is_valid():
                    b = B.objects.update(**b_data)
                    instance.b.add(b)
                else:
                    raise exceptions.ValidationError(todo_serializer.errors)
        return instance

class BSerializer(serializers.ModelSerializer):
    class Meta:
        model = B
        fields = '__all__'
        read_only_fields = ['id']

И модели:

class A(models.Model):
    name = models.CharField('Name', max_length=250)
    content = models.TextField('Content')
    b = models.ManyToManyField('bs.B', blank=True, null=True, verbose_name='b', related_name='as')

class B(models.Model):
    name = models.CharField('Name', max_length=250)
    description = models.TextField('Description')

Проблема, с которой я столкнулся, заключается в том, что во время обновления (PATCH) при печати bs_data все, что я получаю, это

[OrderedDict([('name', 'test'), ('description', 'none')]),
 OrderedDict([('name', 'another'), ('description', 'one')])]

И я не могу обновить все вложенные B объекты - каждый вложенный объект получает содержимое последнего предоставленного объекта (поэтому в приведенном выше примере каждый вложенный объект будет заполнен «другим» именем и «одним» описанием). Если бы у меня был идентификатор объекта, это было бы довольно просто, но оно не передается методу validated_data в update(). Я пытался добавить

id = serializers.IntegerField(required=False)

Но все еще без идентификатора объекта validated_data Я тоже попробовал ReadOnlyField(), тоже не повезло. По сути, моя цель - передать идентификатор объекта из вложенного объекта, чтобы я мог ссылаться на него и изменять. Это единственное уникальное поле в моей модели. Я использую drf-writable-nested lib для обработки вложенной сериализации.

...