Cette solution est presque similaire aux autres solutions publiées ici mais présente une légère différence en termes de problème de répétition des enfants au niveau de la racine (si vous pensez que c'est un problème). À titre d'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 produira 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, la représentation parent category
a 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 du au child category
niveau de la racine.
Comme certaines personnes demandent dans les sections de commentaires des réponses publiées ci-dessus, comment pouvons-nous arrêter cette répétition enfant au niveau de la racine , il suffit de filtrer votre jeu de requête avec parent=None
, comme suit
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é. Cette approche d'utilisation RecursiveSerializer
est également coûteuse. Mieux si vous utilisez d'autres options qui sont sujettes aux performances.