Это решение почти аналогично другим решениям, размещенным здесь, но имеет небольшую разницу с точки зрения проблемы повторения дочерних элементов на корневом уровне (если вы думаете, что это проблема). Для примера
class RecursiveSerializer(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class CategoryListSerializer(ModelSerializer):
sub_category = RecursiveSerializer(many=True, read_only=True)
class Meta:
model = Category
fields = (
'name',
'slug',
'parent',
'sub_category'
)
и если у вас есть это мнение
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Это даст следующий результат:
[
{
"name": "parent category",
"slug": "parent-category",
"parent": null,
"sub_category": [
{
"name": "child category",
"slug": "child-category",
"parent": 20,
"sub_category": []
}
]
},
{
"name": "child category",
"slug": "child-category",
"parent": 20,
"sub_category": []
}
]
Здесь parent category
есть a, child category
а представление json - это именно то, что мы хотим представить.
но вы можете видеть, что child category
на корневом уровне есть повторение .
Поскольку некоторые люди спрашивают в разделах комментариев к опубликованным выше ответам, как мы можем остановить это дочернее повторение на корневом уровне , просто отфильтруйте свой набор запросов parent=None
, как показано ниже
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
это решит проблему.
ПРИМЕЧАНИЕ. Этот ответ может не иметь прямого отношения к вопросу, но проблема каким-то образом связана. К тому же такой подход к использованию RecursiveSerializer
стоит дорого. Лучше, если вы будете использовать другие варианты, которые зависят от производительности.