Django REST Serializer haciendo llamadas a la base de datos N + 1 para una relación anidada múltiple, 3 niveles

Tengo una situación en la que mi modelo tiene una relación de clave externa:

# models.py
class Child(models.Model):
    parent = models.ForeignKey(Parent,)

class Parent(models.Model):
    pass

y mi serializador:

class ParentSerializer(serializer.ModelSerializer):
    child = serializers.SerializerMethodField('get_children_ordered')

    def get_children_ordered(self, parent):
        queryset = Child.objects.filter(parent=parent).select_related('parent')
        serialized_data = ChildSerializer(queryset, many=True, read_only=True, context=self.context)
        return serialized_data.data

    class Meta:
        model = Parent

Cuando llamo a Parent en mi punto de vista para N número de padres, Django hace N número de llamadas a la base de datos dentro del serializador cuando atrapa a los niños. ¿Hay alguna forma de hacer que TODOS los niños para TODOS los padres minimicen la cantidad de llamadas a la base de datos?

He intentado esto pero no parece resolver mi problema:

class ParentList(generics.ListAPIView):

    def get_queryset(self):
        queryset = Parent.objects.prefetch_related('child')
        return queryset

    serializer_class = ParentSerializer
    permission_classes = (permissions.IsAuthenticated,)

EDITAR

He actualizado el siguiente código para reflejar los comentarios de Alex ... que resuelve el N + 1 para una relación anidada.

# serializer.py
class ParentSerializer(serializer.ModelSerializer):
    child = serializers.SerializerMethodField('get_children_ordered')

    def get_children_ordered(self, parent):
        # The all() call should hit the cache
        serialized_data = ChildSerializer(parent.child.all(), many=True, read_only=True, context=self.context)
        return serialized_data.data

    class Meta:
            model = Parent

# views.py
class ParentList(generics.ListAPIView):

    def get_queryset(self):
        children = Prefetch('child', queryset=Child.objects.select_related('parent'))
        queryset = Parent.objects.prefetch_related(children)
        return queryset

    serializer_class = ParentSerializer
    permission_classes = (permissions.IsAuthenticated,)

Ahora digamos que tengo un modelo más, que es un nieto:

# models.py
class GrandChild(models.Model):
    parent = models.ForeignKey(Child,)

class Child(models.Model):
    parent = models.ForeignKey(Parent,)

class Parent(models.Model):
    pass

Si pongo lo siguiente en miviews.py para los padresqueryset:

queryset = Parent.objects.prefetch_related(children, 'children__grandchildren')

No parece que esos nietos estén siendo trasladados al ChildSerializer y, por lo tanto, nuevamente estoy ejecutando otro problema N + 1. ¿Alguna idea sobre este?

EDITAR 2

Quizás esto proporcionará claridad ... Quizás la razón por la que todavía me encuentro con llamadas a la base de datos N + 1, es porque mis clases de hijos y nietos son polimórficas ... es decir

# models.py
class GrandChild(PolymorphicModel):
    child = models.ForeignKey(Child,)

class GrandSon(GrandChild):
    pass

class GrandDaughter(GrandChild):
    pass

class Child(PolymorphicModel):
    parent = models.ForeignKey(Parent,)

class Son(Child):
    pass

class Daughter(Child):
    pass

class Parent(models.Model):
    pass

y mis serializadores se parecen más a esto:

# serializer.py
class ChildSerializer(serializer.ModelSerializer):
    grandchild = serializers.SerializerMethodField('get_children_ordered')

    def to_representation(self, value):
        if isinstance(value, Son):
            return SonSerializer(value, context=self.context).to_representation(value)
        if isinstance(value, Daughter):
            return DaughterSerializer(value, context=self.context).to_representation(value)

    class Meta:
        model = Child

class ParentSerializer(serializer.ModelSerializer):
    child = serializers.SerializerMethodField('get_children_ordered')

    def get_children_ordered(self, parent):
        queryset = Child.objects.filter(parent=parent).select_related('parent')
        serialized_data = ChildSerializer(queryset, many=True, read_only=True, context=self.context)
        return serialized_data.data

    class Meta:
        model = Parent

Además de lo mismo para Grandaughter, Grandson, te ahorraré los detalles en código, pero creo que entiendes la imagen.

Cuando ejecuto mi vista de ParentList y monitorizo las consultas de DB, obtengo algo similar a miles de consultas, solo para un puñado de padres.

Si ejecuto el mismo código en el shell django, puedo realizar la misma consulta en no más de 25 consultas. Sospecho que tal vez tenga algo que ver con el hecho de que estoy usando la biblioteca django-polymorphic. La razón es que hay una tabla de base de datos Child y GrandChild, además de cada tabla Hijo / Hija, Nieto / Nieta, para un total de 6 tablas. a través de esos objetos. Entonces mi instinto me dice que me estoy perdiendo esas tablas polimórficas.

¿O tal vez hay una solución más elegante para mi modelo de daata?

Respuestas a la pregunta(2)

Su respuesta a la pregunta