Эффективный способ получить количество связанных моделей в Django ORM - PullRequest
2 голосов
/ 07 октября 2019

Я работаю над Django 1.10 и PostgreSQL9.6

У меня есть две модели в моем проекте: Order и Customer. Также я использую Django auth.User для хранения учетных данных для входа.

Вот фрагмент кода:

from django.contrib.auth.models import User
from django.db import models


class Order(models.Model):
    created_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name='created_orders')
    # ... other fields ...

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # ... other fields ...

Теперь мне нужно показать таблицу customers и показатьколичество ордеров, созданных каждым из них.

Код прямой очереди:

for customer in Customer.objects.all():
    print(customer.user.created_orders.count())

Теперь мне нужно избежать проблемы N + 1 и заставить Django извлекать все данные с постоянным числомзапросы.

Я пытался написать что-то вроде:

    query = Customer.objects.select_related('user').annotate(
        orders_count=Count('user.created_orders')
    )

Но это дает мне ошибку вроде Cannot resolve keyword 'user.created_orders' into field.

Можете ли вы помочь мне с этим?

1 Ответ

1 голос
/ 07 октября 2019

Вы должны не использовать точку (.) здесь, но два последовательных подчеркивания (__):

query = Customer.objects.select_related('user').annotate(
    orders_count=Count('<b>user__created_orders</b>')
)

Обратите внимание, что вы не необходимо .select_related('user'), чтобы аннотировать набор запросов. Однако если вы планируете использовать .user позже в своей логике, это действительно может повысить производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...