Solusi ini hampir mirip dengan solusi lain yang diposting di sini tetapi memiliki sedikit perbedaan dalam hal masalah pengulangan anak di tingkat akar (jika Anda menganggapnya sebagai masalah). Sebagai contoh
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'
)
dan jika Anda memiliki pandangan ini
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Ini akan menghasilkan hasil sebagai berikut,
[
{
"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": []
}
]
Di sini representasi parent category
has a child category
dan json persis seperti yang kita ingin wakili.
tetapi Anda dapat melihat ada pengulangan child category
pada level root.
Karena beberapa orang bertanya di bagian komentar dari jawaban yang diposting di atas bahwa bagaimana kami bisa menghentikan pengulangan turunan ini di tingkat akar , cukup filter queryset Anda dengan parent=None
, seperti berikut ini
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
itu akan menyelesaikan masalah.
CATATAN: Jawaban ini mungkin tidak secara langsung terkait dengan pertanyaan, tetapi masalahnya terkait. Juga pendekatan penggunaan RecursiveSerializer
ini mahal. Lebih baik jika Anda menggunakan opsi lain yang rawan kinerja.