Esta solución es casi similar a las otras soluciones publicadas aquí, pero tiene una ligera diferencia en términos del problema de repetición de niños en el nivel raíz (si cree que es un problema). Para un ejemplo
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'
)
y si tienes esta vista
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.all()
serializer_class = CategoryListSerializer
Esto producirá el siguiente resultado,
[
{
"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": []
}
]
Aquí parent category
tiene una child category
y la representación json es exactamente lo que queremos que represente.
pero puede ver que hay una repetición del child category
en el nivel raíz.
Como algunas personas preguntan en las secciones de comentarios de las respuestas publicadas anteriormente, ¿cómo podemos detener esta repetición secundaria en el nivel raíz? Simplemente filtre su conjunto de consultas con parent=None
, como el siguiente
class CategoryListAPIView(ListAPIView):
queryset = Category.objects.filter(parent=None)
serializer_class = CategoryListSerializer
resolverá el problema.
NOTA: Es posible que esta respuesta no esté directamente relacionada con la pregunta, pero el problema está relacionado de alguna manera. Además, este enfoque de uso RecursiveSerializer
es caro. Mejor si usa otras opciones que sean propensas al rendimiento.