Рекурсивный и вложенный сериализатор для 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):

    ...

Этот миксин позволяет вложенные отношения для:

  1. OneToOneField()
  2. ForeingKey()
  3. ManyToManyField()
  4. GenericRelation()

djangorestframework-recursive решил для меня эту проблему просто:

children = serializers.ListField(child=RecursiveField())
Вернуться на верх