Как сделать 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

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

8 ответов

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

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

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

Django также имеет функцию " последний (имя_поля = 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

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

соль 01:

      from .models import MyMODEL

max_rating = MyMODEL.objects.order_by('-rating').first()

соль 02:

      from django.db.models import Max
from .models import MyMODEL

max_rating = MyMODEL.objects.aggregate(Max('rating'))

Если вы также хотите получить значение, отличное от None если таблица пуста (например, 0), объедините Maxс Coalesce:

      from django.db.models import Max, Value
from django.db.models.functions import Coalesce

max_rating = SomeModel.objects.aggregate(
    max_rating=Coalesce(Max('rating'), Value(0))
)['max_rating']

Чтобы, возможно, улучшить ответ @afahim в отношении комментария @Raydel Miranda, если вам нужен случайный комментарий. Если хотите все, используйте только фильтр

      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.aggregate(Max('rating'))['rating__max']
return App.objects.filter(rating=max_rating).first()

может кому поможет в беде

      def get_queryset(self):
    sorgu = Sunum.objects.values('id', 'firma', 'projeadi', 'sunumdurum__durum', 'sunumdurum__aciklama'
                           ).annotate(max_rank=Max('sunumdurum__kayittarihi'))
    szlk={}
    for sor in sorgu :
        ana = sor['id'], sor['firma'], sor['projeadi']
        dana = sor['sunumdurum__durum'], sor['sunumdurum__aciklama'], sor['max_rank']
        szlk.setdefault(ana, dana)
    return szlk

Для будущих читателей вы можете использоватьannotateвместоaggregateесли вам нужны записи/другие поля, а не только максимальное значение.

т.е. эквивалентно этому SQL-запросу

      SELECT
  first_name,
  last_name,
  Max(height) max_height
FROM patients;

Теперь одна проблема заключается в том, что передача агрегатной функции в аннотации вызовет группу по

      from django.db.models import Max

Patients.objects.values('height').annotate(max_height=Max('height'))

>>>
SELECT "patients"."height",
       MAX("patients"."height") AS "max_height"
FROM "patients"
GROUP BY "patients"."height"

Обходной путь — использовать выражение Func.

      from django.db.models F, Func

Patients.objects.annotate(max_height=Func(F('height'), function='Max'))\
.values('first_name', 'last_name', 'max_height')

>>>
SELECT "patients"."first_name",
       "patients"."last_name",
       Max("patients"."height") AS "max_height"
FROM "patients"

посмотрите это , если вам нужно сделать это в подзапросе

Другие вопросы по тегам