To rozwiązanie jest prawie podobne do innych opublikowanych tutaj rozwiązań, ale ma niewielką różnicę pod względem problemu z powtarzaniem się dzieci na poziomie głównym (jeśli uważasz, że jest to problem). Dla przykładu
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'
)
i jeśli masz taki pogląd
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
To da następujący wynik,
[
{
"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": []
}
]
Tutaj parent category
machild category
a reprezentacja json jest dokładnie tym, co chcemy, aby była reprezentowana.
ale widać, że jest powtórzenie child category
na poziomie głównym.
Ponieważ niektórzy ludzie pytają w sekcjach komentarzy powyżej opublikowanych odpowiedzi, że jak możemy zatrzymać to powtórzenie dziecka na poziomie głównym , po prostu przefiltruj swój zestaw zapytań za pomocą parent=None
, jak poniżej
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
to rozwiąże problem.
UWAGA: Ta odpowiedź może nie być bezpośrednio związana z pytaniem, ale problem jest w jakiś sposób powiązany. Również takie podejście RecursiveSerializer
jest kosztowne. Lepiej, jeśli używasz innych opcji, które są podatne na wydajność.