Хотя работает другой ответ (для создания и получения), всегда лучше использовать сериализаторы для сохранения данных, когда это возможно. В будущем вам может потребоваться какая-то настраиваемая проверка или вам может потребоваться переопределить метод создания по умолчанию для вложенного сериализатора.
Если вы не выполните следующие действия, вы пропустите все функции, которые предоставляет класс сериализатора и, возможно, потребуются написать весь свой код самостоятельно в функции create вашего основного сериализатора, который будет грязным.
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = ReturnKitsProducts
fields = "__all__"
class ReturnKitsSerializer(serializers.ModelSerializer):
items = ItemSerializer(many=True) # same as
class Meta:
model = ReturnKits
fields = "__all__"
def validate_items(self, value):
serializer = ItemSerializer(data=value, many=True)
if serializer.is_valid():
return serializer # this will be finally received and used in create function of main serializer
else:
raise serializers.ValidationError(serializer.errors)
def create(self, validated_data):
items = validated_data.pop('items')
r = ReturnKits.objects.create(**validated_data)
for item in items:
r.items.add(item.save()) # save each serializer (already validated) and append saved object
return r
class ReturnSerializer(serializers.ModelSerializer):
kits = ReturnKitsSerializer(many=True)
def validate_kits(self, value):
serializer = ReturnKitsSerializer(data=value, many=True)
if serializer.is_valid():
return serializer
else:
raise serializers.ValidationError(serializer.errors)
class Meta:
model = Return
fields = "__all__"
def create(self, validated_data):
# IMP: At this point all the data (including nested) will have been validated, so no error will throw when saving the data
kits = validated_data.pop('kits', None)
instance = Return.objects.create(**validated_data)
for kit in kits:
i = kits.save() # save each serializer (already validated) and get a object
instance.kits.add(i)
return instance
Этот код будет работать для create и get. Если вы хотите обновить все свои данные сразу, вам следует разработать подход.
Вы можете попробовать подход, который я использую:
Обновление данных с их вложенными данными
Если словарь содержит поле id
, соответствующие вложенные данные будут обновлены.
Если словарь не содержит поля id
, новые вложенные данные будут создано.
Если словарь содержит только id
в качестве ключа, вложенные данные будут удалены.
Нет необходимости предоставлять вложенные данные, которые не нужно обновлять или удалять.
https://github.com/SagarKAdhikari/drf-nested-relations: библиотека, в которой вы можете проверять и сохранять / обновлять вложенные данные в любая глубина , хотя она работает только для общих c отношений и внешних ключей (поскольку в моем проекте требовалось только это). Вы можете попробовать понять код и имплементацию, если ваши вложенные отношения намного глубже, чем в настоящее время, и у вас их слишком много.