Django REST Serializer выполняет N + 1 вызов базы данных для нескольких вложенных отношений, 3 уровня

У меня есть ситуация, когда моя модель имеет отношение внешнего ключа:

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

class Parent(models.Model):
    pass

и мой сериализатор:

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

Когда я вызываю Parent в своих представлениях для N number of Parents, Django делает N вызовов базы данных внутри сериализатора, когда он захватывает дочерние элементы. Есть ли способ получить ВСЕХ детей для ВСЕХ Родителей, чтобы минимизировать количество вызовов базы данных?

Я пробовал это, но это не решает мою проблему:

class ParentList(generics.ListAPIView):

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

    serializer_class = ParentSerializer
    permission_classes = (permissions.IsAuthenticated,)

РЕДАКТИРОВАТЬ

Я обновил код ниже, чтобы отразить обратную связь Алекса .... которая решает N + 1 для одного вложенного отношения.

# 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,)

Теперь скажем, у меня есть еще одна модель, которая является внуком:

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

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

class Parent(models.Model):
    pass

Если я размещу следующее в моемviews.py для родителейqueryset:

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

Не похоже, что этих внуков переносят в ChildSerializer, и, таким образом, я снова запускаю еще одну проблему N + 1. Есть мысли по этому поводу?

РЕДАКТИРОВАТЬ 2

Возможно, это обеспечит ясность ... Возможно, причина, по которой я все еще сталкиваюсь с вызовами из базы данных N + 1, заключается в том, что и мои дети, и классы внуков являются полиморфными .... т.е.

# 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

и мои сериализаторы выглядят больше так:

# 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

Плюс то же самое для внучки, внук, я сэкономлю вам детали в коде, но я думаю, вы понимаете.

Когда я запускаю свое представление для ParentList и отслеживаю запросы к БД, я получаю что-то вроде тысячных запросов только для нескольких родителей.

Если я запускаю один и тот же код в оболочке django, я могу выполнить один и тот же запрос не более чем в 25 запросах. Я подозреваю, что это может быть связано с тем, что я использую django-polymorphic библиотеку? Причина в том, что есть таблица базы данных Child и GrandChild, в дополнение к каждой таблице Son / Daughter, Grandson / Granddaughter, всего 6 таблиц. через эти объекты. Так что моя интуиция говорит мне, что я скучаю по этим полиморфным таблицам.

Или, может быть, есть более элегантное решение для моей модели Daata?

Ответы на вопрос(2)

Ваш ответ на вопрос