Агрегация модели Джанго
У меня есть простая иерархическая модель с человеком и 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 ответа
Я не уверен на 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
Если вы хотите, чтобы одна RunScore предоставлялась только для одного человека, вы можете использовать odering и ограничить набор запросов до 1 объекта. Что-то вроде этого:
Person.runningscore_set.order_by('-time')[0]
Вот документ об ограничении наборов запросов: