Как сделать SELECT MAX в Django? - PullRequest
68 голосов
/ 10 мая 2009

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

Я использую этот код:

def get_best_argument(self):
    try:
        arg = self.argument_set.order_by('-rating')[0].details
    except IndexError:
        return 'no posts'
    return arg

рейтинг является целым числом

Ответы [ 3 ]

128 голосов
/ 10 мая 2009

См. это . Ваш код будет выглядеть примерно так:

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]

Обратите внимание, что это приведет к ошибке, если набор запросов будет пустым, т. Е. Если ни один аргумент не соответствует запросу (поскольку часть [0] вызовет IndexError). Если вы хотите избежать такого поведения и вместо этого просто вернуть None, используйте .first():

arg = args.order_by('-rating').first() # may return None
64 голосов
/ 14 июня 2013

Django также имеет функцию ' latest (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
40 голосов
/ 21 июня 2012

Я проверил это для своего проекта, он находит максимум / мин за 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)).

...