Как решить N+1 проблему двойной prefetch_related с помощью order_by в Django?

В models.py простая структура...

Model A(parent of B) <- Model B(parent of C) <- Model C

А в файле views.py я хочу использовать как prefetch_related в B,C, так и order_by в b.

a_obj = A.objects.prefetch_related(Prefetch("b__c", queryset=B.objects.all().order_by("-order")))

но в serializers.py я не могу получить доступ к данным c.

def get_data(self, group):
   for b in group.b.all():
      print(b.c.all())  # ===> result: queryset [B object(pk)]

А также я попробовал другой способ в views.py и serializers.py

# views.py
a_obj = A.objects.prefetch_related("b__c")

# serializers.py
def get_data(self, group):
   for b in group.b.all().order_by("-order"):
      print(b.c.all())  # ===> N+1 query occurred

Но у меня проблема с N+1.

Что мне делать?

Все очень просто. Отредактируйте в models.py то, что нуждается в упорядочивании.

И я удалил все свои коды в views.py и serializers.py

class B(models.Model):
   ...
   class Meta:
      ordering=['-order']

Если вы не хотите использовать "глобальное" упорядочивание, вы можете работать с каскадным Prefetch:

a_obj = A.objects.prefetch_related(
    Prefetch('b', queryset=B.objects.prefetch_related('c').order_by('-order'))
)
Вернуться на верх