Diese Lösung ähnelt fast den anderen hier veröffentlichten Lösungen, weist jedoch einen geringfügigen Unterschied in Bezug auf das Problem der Wiederholung von Kindern auf der Stammebene auf (wenn Sie der Meinung sind, dass dies ein Problem ist). Zum Beispiel
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'
)
und wenn Sie diese Ansicht haben
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Dies führt zu folgendem Ergebnis:
[
{
"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": []
}
]
Hier parent category
hat child category
die a- und die json-Darstellung genau das, was wir wollen, dass sie dargestellt wird.
aber Sie können sehen, dass es eine Wiederholung der child category
auf der Wurzelebene gibt.
Da einige Leute in den Kommentaren der oben veröffentlichten Antworten fragen, wie wir diese untergeordnete Wiederholung auf der Stammebene stoppen können , filtern Sie einfach Ihr Abfrageset mit parent=None
wie folgt
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
es wird das Problem lösen.
HINWEIS: Diese Antwort steht möglicherweise nicht in direktem Zusammenhang mit der Frage, aber das Problem hängt irgendwie zusammen. Auch dieser Verwendungsansatz RecursiveSerializer
ist teuer. Besser, wenn Sie andere Optionen verwenden, die leistungsanfällig sind.