web-dev-qa-db-ja.com

DjangoでSELECT MAXを実行する方法は?

クエリを実行してフィールドの最大値を取得する方法は次のとおりです。

私はこのコードを使用しています:

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

評価は整数です

72
Johnd

this を参照してください。コードは次のようになります。

_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
_
134
Sasha Chedygov

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
65

私のプロジェクトでこれをテストしましたが、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)付近)を取得するのではなく、最大要素の1つを効率的に取得することが保証されます。

41
afahim