агрегированные поля Django? - PullRequest
2 голосов
/ 26 ноября 2009

У меня есть модель с именем Item, с отношением m2m к пользователю («владелец»).

Для каждого элемента мне нужно подсчитать пользователей, которым он принадлежит. Это достаточно просто с помощью annotate ()

Но тогда мне нужно рассчитать соотношение между владельцами определенного пола и общим количеством владельцев для каждого элемента. Например, если продукт принадлежит 5 мужчинам из 5 пользователей, коэффициент составляет 0,4.

Какой лучший способ сделать это?

Ответы [ 2 ]

3 голосов
/ 04 декабря 2009

Чтобы сделать это с ORM, вам нужны условные агрегаты, которые не поддерживаются в Django. http://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django предлагает хакерское решение, которое может работать.

Если вам не нужно сортировать по соотношению, вы можете сделать два вызова для аннотирования, а затем вычислить это соотношение в Python. Что-то вроде:

items = Item.objects.annotate(ucount=Count('users')).annotate(ccount=CountIf(<condition>))
for item in items:
    item.ratio = item.ucount / item.ccount

Если вы не хотите этого делать, я бы порекомендовал использовать метод extra () и некоторые пользовательские sql для получения необходимой дополнительной информации. Документация по этому методу находится на странице документации Django Queryset API.

0 голосов
/ 27 ноября 2009

Просто у меня на голове может сработать что-то вроде следующего. Итерируйте его, чтобы получить идеальное решение, если хотите:

items = Item.objects.annotate(Count('users'))

for item in items:
    total = item.users__count
    num_males = item.users.filter(gender='M').count()
    num_females = item.users.filter(gender='F').count()
...