I know there are a few other threads about this topic but none of the solutions seem to work for me.
I have a simple django-treebeard model that allows me to bulk add nested children to a parent via a load_bulk
model method.
The POST payload is essentially:
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
}
I have a view that takes the parent_id
and the items
list of objects from the payload
and passes it to load_bulk
to create all the nested objects:
Model.load_bulk(items, parent=Model.objects.get(id=parent_id))
It works fine for the top-level of items
but seems to ignore the nested children
. In fact, I can't even get the get_children
method in my serializer (commented below) to run.
# 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}
Edit: So SerializerMethodField is read-only..?
CodePudding user response:
I had the same problem before what I used was a package from drf-writable-nested.
What you can do is simply inherit the WritableNestedModelSerializer
into your ModelSerializer.
ex:
class MyModelSerializer(WritableNestedModelSerializer):
...
This mixin allows nested relationship for:
- OneToOneField()
- ForeingKey()
- ManyToManyField()
- GenericRelation()
CodePudding user response:
djangorestframework-recursive solved it for me simple:
children = serializers.ListField(child=RecursiveField())