Как решить 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'))
)