Django: как агрегировать/аннотировать отношения «многие ко многим»?

У меня есть модель Person и модель Tag с m2m между ними.

Мне нужно извлечь тег, связанный с большинством записей в заданном наборе запросов Person, вместе со счетчиком.

Есть ли элегантный и эффективный способ извлечь это с помощью Django ORM?

Еще лучше, есть ли способ получить все распределение тегов с помощью какой-либо аннотации? Как вообще можно вывести все объекты, подключенные к подмножеству объектов, подключенных через m2m?

Спасибо!


person GJ.    schedule 31.08.2010    source источник


Ответы (2)


Это даст вам наиболее частый тег:

from django.db.models import Count
Tag.objects.filter(person__yourcriterahere=whatever [, morecriteria]).annotate(cnt=Count('person')).order_by('-cnt')[0]
person GJ.    schedule 02.09.2010
comment
Идеальный. Просто небольшая опечатка: .object. должны быть .objects. - person Simon Steinberger; 06.07.2014
comment
Потрясающе, большое спасибо. Для таких глупых людей, как я, вы должны импортировать: from django.db.models import Count - person simonbogarde; 16.02.2019

Мне нужно извлечь тег, связанный с большинством записей в заданном наборе запросов Person, вместе со счетчиком.

Я сталкивался с подобной проблемой раньше. В моем случае отношения m2m были определены между моделями Unit и Weapon. Я использовал следующий запрос, чтобы узнать количество оружия, используемого каждым Unit, и отсортировать их в порядке убывания количества оружия.

from django.db.models import Count
q = Unit.objects.all().annotate(count = Count('weapons')).order_by('-count')

Я бы скорректировал запрос для вашего требования следующим образом:

q = User.objects.all().annotate(count = Count('tag')).order_by('-count')
person Manoj Govindan    schedule 01.09.2010