Esta solução é quase semelhante às outras soluções postadas aqui, mas tem uma pequena diferença em termos de problema de repetição de criança no nível raiz (se você acha que é um problema). Por exemplo
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'
)
e se você tem essa visão
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Isso produzirá o seguinte resultado,
[
{
"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": []
}
]
Aqui, o parent category
tem child category
ae a representação json é exatamente o que queremos que seja representado.
mas você pode ver que há uma repetição do child category
no nível raiz.
Como algumas pessoas estão perguntando nas seções de comentários das respostas postadas acima, como podemos parar essa repetição infantil no nível raiz , basta filtrar seu queryset com parent=None
, como a seguir
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
vai resolver o problema.
NOTA: Esta resposta pode não estar diretamente relacionada à pergunta, mas o problema está de alguma forma relacionado. Além disso, essa abordagem de uso RecursiveSerializer
é cara. Melhor se você usar outras opções que são propensas ao desempenho.