Как сделать SELECT MAX в Django?
У меня есть список объектов, как я могу запустить запрос, чтобы указать максимальное значение поля:
Я использую этот код:
def get_best_argument(self):
try:
arg = self.argument_set.order_by('-rating')[0].details
except IndexError:
return 'no posts'
return arg
рейтинг - целое число
Ответы
Ответ 1
Смотрите это. Ваш код будет выглядеть примерно так:
from django.db.models import Max
# Generates a "SELECT MAX..." query
Argument.objects.aggregate(Max('rating')) # {'rating__max': 5}
Вы также можете использовать это на существующих наборах запросов:
from django.db.models import Max
args = Argument.objects.filter(name='foo') # or whatever arbitrary queryset
args.aggregate(Max('rating')) # {'rating__max': 5}
Если вам нужен экземпляр модели, который содержит это максимальное значение, то размещенный вами код, вероятно, является лучшим способом сделать это:
arg = args.order_by('-rating')[0]
Обратите внимание, что это приведет к ошибке, если IndexError
запросов будет пустым, то есть если никакие аргументы не соответствуют запросу (потому что часть [0]
вызовет IndexError
). Если вы хотите избежать такого поведения и вместо этого просто вернуть None
в этом случае, используйте .first()
:
arg = args.order_by('-rating').first() # may return None
Ответ 2
Django также имеет функцию last (field_name = None) ', которая находит последнюю (максимальное значение). Он не только работает с полями даты, но также со строками и целыми числами.
Вы можете указать имя поля при вызове этой функции:
max_rated_entry = YourModel.objects.latest('rating')
return max_rated_entry.details
Или вы уже можете указать это имя в ваших метаданных ваших моделей:
from django.db import models
class YourModel(models.Model):
#your class definition
class Meta:
get_latest_by = 'rating'
Теперь вы можете вызывать "latest()" без каких-либо параметров:
max_rated_entry = YourModel.objects.latest()
return max_rated_entry.details
Ответ 3
Я тестировал это для своего проекта, он находит max/min в O (n) времени:
from django.db.models import Max
#Find the maximum value of the rating, and then get the record with that rating. Notice the double underscores in rating__max
max_rating = App.objects.all().aggregate(Max('rating'))['rating__max']
return App.objects.get(rating = max_rating)
Это гарантирует, что вы получите один из максимальных элементов эффективно, вместо того, чтобы сортировать всю таблицу и получать верхнюю часть (вокруг O (nlogn)).