我有一个对象列表,如何运行查询以给出字段的最大值:
我正在使用此代码:
def get_best_argument(self):
try:
arg = self.argument_set.order_by('-rating')[0].details
except IndexError:
return 'no posts'
return arg
评分是整数
Answers:
看到这个。您的代码将如下所示:
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]
请注意,如果queryset为空,即没有参数匹配查询,这将出错(因为该[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()
可以与非日期字段一起使用,但这是实施的副作用。您应该使用<your-queryset>.order_by('<interested-field>').first()
或<your-queryset>.order_by('<interested-field>').last()
确保即使Django开发人员将更改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))。