2009-05-10 2 views
48

У меня есть список объектов, как я могу запустить запрос, чтобы получить максимальное значение поля:Как сделать 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 

рейтинг представляет собой целое число

ответ

97

см this. Ваш код будет выглядеть примерно следующим образом:

from django.db.models import Max 
# Generates a "SELECT MAX..." statement 
Argument.objects.all().aggregate(Max('rating')) 

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

from django.db.models import Max 
args = Argument.objects.all() 
# Calculates the maximum out of the already-retrieved objects 
args.aggregate(Max('rating')) 

Это тестировался, так что я возможно, что-то допустил ошибку, но там вы идете.

+0

опечатка: "import Avg" -> "import Max"? – Tom

+0

да я сделал это изменение в своем коде – Johnd

+4

Мне нужен объект аргумента аргумента, который имеет этот Макс, поэтому я могу распечатать поле сведений. Атрибут args.aggregate (Max ('rating')) возвращает наивысший рейтинг. Я ищу arg с самым высоким рейтингом. – Johnd

37

Я проверил это для моего проекта, он находит максимальное/мин в O (п):

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)).

+4

Big-O иногда не проявляется на практике, особенно для меньшего n, где важны коэффициенты и реализация. Ваш код находится в python/django, который скомпилирован в байт-код и может быть оптимизирован или не оптимизирован. Вероятно, база данных написана на языке, который оптимизирован и скомпилирован для машинных инструкций. Кроме того, у базы данных нет реальной причины сортировки, если функция ищет только максимальное значение. Я хотел бы видеть данные синхронизации, прежде чем мне будет удобно использовать код ручной сборки над встроенной функцией базы данных. – benevolentprof

46

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' 

Теперь вы можете позвонить «последним () 'без каких-либо параметров:

max_rated_entry = YourModel.objects.latest() 
return max_rated_entry.details 
+3

Это отличный способ использования 'latest()'. Если вам нужна запись с минимальным значением, вы можете использовать 'earlyliest()'. – SaeX

+1

'latest()' и 'earlyliest()' также работают с неточным полем, но это побочный эффект реализации. Вы должны использовать '<ваш-queryset> .order_by ('<интересуемое поле>'). First()' или '<ваш-queryset> .order_by ('<интересуемое поле>').last() ', чтобы гарантировать, что ваш код будет работать, даже если разработчики Django изменят реализацию' latest() 'и' earlyely() 'для работы только с полями даты. – mrnfrancesco

 Смежные вопросы

  • Нет связанных вопросов^_^