Cette solution est presque similaire aux autres solutions postées ici mais présente une légère différence en termes de problème de répétition d'enfants au niveau de la racine (si vous pensez que c'est un problème). Par exemple
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'
)
et si vous avez cette vue
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Cela donnera le résultat suivant,
[
{
"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": []
}
]
Ici, le parent category
a un child category
et la représentation json est exactement ce que nous voulons qu'elle représente.
mais vous pouvez voir qu'il y a une répétition de la child category
au niveau de la racine.
Comme certaines personnes le demandent dans les sections de commentaires des réponses postées ci-dessus que comment pouvons-nous arrêter cette répétition d'enfants au niveau de la racine ? il suffit de filtrer votre ensemble de requêtes avec parent=None
comme le suivant
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
cela résoudra le problème.
REMARQUE : Cette réponse n'est peut-être pas directement liée à la question, mais le problème est en quelque sorte lié. De plus, cette approche consistant à utiliser RecursiveSerializer
est coûteux. Il vaut mieux utiliser d'autres options qui sont sujettes aux performances.