Я создал два сериализатора - 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 для обработки вложенной сериализации.