Агрегация модели Джанго - PullRequest
1 голос
/ 05 июня 2011

У меня есть простая иерархическая модель с Person и RunningScore как ребенок. В этой модели хранятся данные о набранных очках многих пользователей, упрощенно что-то вроде:

class Person(models.Model):
   firstName = models.CharField(max_length=200)
   lastName = models.CharField(max_length=200)  

class RunningScore(models.Model):
   person = models.ForeignKey('Person', related_name="scores")
   time = models.DecimalField(max_digits=6, decimal_places=2)   

Если я получаю одного человека, он идет со всеми связанными с ним RunningScores, и это стандартное поведение. Мой вопрос очень прост: если я хочу получить человека с ребенком, имеющим только RunningScore (предположим, лучший результат, мин. (Время)), как я могу это сделать? Я прочитал официальную документацию по Django, но не нашел решение.

Ответы [ 2 ]

0 голосов
/ 06 июня 2011

Если вы хотите, чтобы один RunningScore был только для одного человека, вы можете использовать odering и ограничить ваш набор запросов 1 объектом. Примерно так:

Person.runningscore_set.order_by('-time')[0]

Вот документация по ограниченным наборам запросов:

https://docs.djangoproject.com/en/1.3/topics/db/queries/#limiting-querysets

0 голосов
/ 05 июня 2011

Я не уверен на 100%, понял ли я то, что вы имеете в виду, но, возможно, это поможет:

from django.db.models import Min
Person.objects.annotate(min_running_time=Min('time'))

Набор запросов будет извлекать объекты Person с min_running_time дополнительным атрибутом.

Вы также можете добавить фильтр:

Person.objects.annotate(min_running_time=Min('time')).filter(firstName__startswith='foo')

Доступ к атрибуту min_running_time первого объекта:

first_person = Person.objects.annotate(min_running_score=Min('time'))[0]
print first_person.min_running_time

РЕДАКТИРОВАНИЕ:

Вы можетеОпределите метод или свойство, например, следующее, чтобы получить связанный объект:

class Person(models.Model):
...
    @property
    def best_runner(self):
        try:
            return self.runningscore_set.order_by('time')[0]
        except IndexError:
            return None
...