オブジェクトのリストがあります。クエリを実行してフィールドの最大値を指定するにはどうすればよいですか。
私はこのコードを使用しています:
def get_best_argument(self):
try:
arg = self.argument_set.order_by('-rating')[0].details
except IndexError:
return 'no posts'
return arg
評価は整数です
回答:
これを参照してください。コードは次のようになります。
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
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
latest()
。最小値のレコードが必要な場合は、を使用できますearliest()
。
latest()
そしてearliest()
、あまりにも非日付フィールドで動作しますが、それは実装の副作用です。Django開発者が変更し、実装が日付フィールドのみで機能するようになった場合でも、<your-queryset>.order_by('<interested-field>').first()
または<your-queryset>.order_by('<interested-field>').last()
を使用してコードが機能することを確認する必要があります。latest()
earliest()
私は自分のプロジェクトでこれをテストしました、それは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.aggregate(Max('rating'))['rating__max']
return App.objects.get(rating=max_rating)
これにより、テーブル全体を並べ替えて最上位(O(n * logn)付近)を取得するのではなく、最大要素の1つを効率的に取得できることが保証されます。