Questa soluzione è quasi simile alle altre soluzioni pubblicate qui, ma presenta una leggera differenza in termini di problema di ripetizione infantile a livello di radice (se pensi che sia un problema). Per un esempio
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 hai questa visione
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Questo produrrà il seguente risultato,
[
{
"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": []
}
]
Qui il file parent category
ha un filechild category
e la rappresentazione json è esattamente ciò che vogliamo che rappresenti.
ma puoi vedere che c'è una ripetizione di child category
a livello di radice.
Poiché alcune persone chiedono nelle sezioni dei commenti delle risposte postate sopra che come possiamo fermare questa ripetizione del bambino a livello di root , filtra semplicemente il tuo set di query con parent=None
, come segue
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
risolverà il problema.
NOTA: questa risposta potrebbe non essere direttamente correlata alla domanda, ma il problema è in qualche modo correlato. Anche questo approccio di utilizzo RecursiveSerializer
è costoso. Meglio se usi altre opzioni che sono soggette a prestazioni.