Django ORM: подсчитать подмножество связанных предметов - PullRequest
1 голос
/ 11 октября 2010

Я ищу способ аннотировать набор запросов с количеством поднаборов связанных элементов. Ниже приведено подмножество моих моделей:

class Person(models.Model):
    Name = models.CharField(max_length = 255)
    PracticeAttended = models.ManyToManyField('Practice',
                                              through = 'PracticeRecord')

class Club(models.Model):
    Name = models.CharField(max_length = 255)
    Slug = models.SlugField()
    Members = models.ManyToManyField('Person')

class PracticeRecord(PersonRecord):
    Person = models.ForeignKey(Person)
    Practice = models.ForeignKey(Practice)

class Practice(models.Model):
    Club = models.ForeignKey(Club, default = None, null = True)
    Date = models.DateField()

Я собираюсь создать набор запросов, в котором будет указано количество конкретных практик клуба, в которых участвует человек. Я уже могу найти общее количество практик этого человека с запросом Person.objects.all().annotate(Count('PracticeRecord'))

Однако я бы хотел как-нибудь прокомментировать количество тренировок, которые человек посещает для определенного клуба.

Я бы предпочел что-то, используя django ORM, не прибегая к написанию сырого SQL.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 11 октября 2010

Однако я бы хотел как-нибудь прокомментировать количество тренировок, которые человек посещает для определенного клуба.

Давайте посмотрим.

Сначала найдите конкретныйclub.

club = Club.objects.get(**conditions)

Далее отфильтруйте всех лиц, которые практиковали в этом клубе.

persons = Person.objects.filter(practicerecord__Practice__Club = club)

Теперь добавьте аннотации к счету.

q = persons.annotate(count = Count('practicerecord'))

Редактировать

Мне удалось успешно выполнить эту работу в моей тестовой настройке: Django 1.2.3, Python 2.6.4, Postgresql 8.4, Ubuntu Karmic.

PS: Хорошая идея ™ - использовать строчные имена для полей.Это значительно упрощает использование синтаксиса двойного подчеркивания (__) для объединения полей.Например, в вашем случае Django автоматически создает practicerecord для каждого Person.Когда вы пытаетесь получить доступ к другим полям PracticeRecord через это поле, вы должны помнить, чтобы использовать регистр заголовка.

Если бы вы использовали строчные буквы, вы могли бы написать:

persons = Person.objects.filter(practicerecord__practice__club = club)
#                                               ^^        ^^  

, что выглядит гораздо более равномерно.

PPS : Это Count('practicerecord') (обратите внимание на нижний регистр).

0 голосов
/ 11 октября 2010

Боюсь, что raw sql - единственный вариант здесь. Во всяком случае, не так страшно и сложно управлять, если вы положите его руководителю модели.

...