Рекурсивный и вложенный сериализатор для CreateAPIView
Я знаю, что есть несколько других тем на эту тему, но ни одно из решений, похоже, не работает для меня.
У меня есть простая модель django-treebeard, которая позволяет мне массово добавлять вложенных детей к родителю через load_bulk
метод модели .
Полезная нагрузка POST по существу такова:
items = [
{"data": {"title": "1"}, children: []},
{"data": {"title": "2"}, children: [
{"data": {"title": "2_1"}, children: []},
{"data": {"title": "2_2"}, children: [
{"data": {"title": "2_2_1"}, children: []},
]},
]},
]
payload = {
"parent_id": parent_id,
"items": items
}
У меня есть представление, которое принимает parent_id
и items
список объектов из payload
и передает его в load_bulk
для создания всех вложенных объектов:
Model.load_bulk(items, parent=Model.objects.get(id=parent_id))
Он отлично работает для верхнего уровня items
, но, похоже, игнорирует вложенные children
. На самом деле, я даже не могу заставить метод get_children
в моем сериализаторе (прокомментированном ниже) работать.
# models.py
class Item(MP_node):
id = UUIDField()
title = CharField()
# views.py
class BulkCreateView(generics.CreateAPIView):
queryset = Item.objects.all()
serializer_class = BulkCreateSerializer
# serializers.py
class BulkCreateSerializer__item(serializers.ModelSerializer):
class Meta:
model = Item
fields = ["title"]
class BulkCreateSerializer__wrapper(serializers.ModelSerializer):
data = TextBulkCreateSerializer__chapter()
children = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ["data", "children"]
def get_children(self, obj):
# Something wrong here? Print statement doesn't even run
print("get_children")
return BulkCreateSerializer__chapterWrapper(obj).data
class BulkCreateSerializer(serializers.ModelSerializer):
parent_id = serializers.UUIDField(required=True)
chapters = serializers.ListField(
child=BulkCreateSerializer__wrapper(), write_only=True
)
class Meta:
model = Item
fields = ["parent_id", "items"]
def create(self, validated_data):
# validated_data only contains top-level items
print("validated_data", validated_data)
parent_id = validated_data["parent_id"]
parent = Item.objects.get(id=parent_id)
chapters = validated_data["chapters"]
create = Text.load_bulk(chapters, parent=parent)
return {"parent_id": parent_id}
У меня была такая же проблема, но я использовал пакет из drf-writable-nested.
Вы можете просто унаследовать WritableNestedModelSerializer
в своем ModelSerializer.
ex:
class MyModelSerializer(WritableNestedModelSerializer):
...
Этот миксин позволяет вложенные отношения для:
- OneToOneField()
- ForeingKey()
- ManyToManyField()
- GenericRelation()
djangorestframework-recursive решил для меня эту проблему просто:
children = serializers.ListField(child=RecursiveField())