sorting查询集的好方法? – Django
我想要做的是这样的:
-
得到最高得分的30位作者(
Author.objects.order_by('-score')[:30]
) -
以
last_name
命令作者
有什么build议么?
关于什么
import operator auths = Author.objects.order_by('-score')[:30] ordered = sorted(auths, key=operator.attrgetter('last_name'))
在Django 1.4及更新版本中,您可以通过提供多个字段进行sorting。
参考: https : //docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
ORDER_BY(*字段)
默认情况下, QuerySet
返回的结果是由模型Meta中的ordering
选项给出的sorting元组ordering
的。 您可以通过使用order_by
方法在基于每个QuerySet的基础上覆盖此值。
例:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
上面的结果将按照score
降序排列,然后按last_name
升序排列。 "-score"
前的负号表示降序。 升序是隐含的。
我只想说明内置解决scheme(仅限于SQL)并不总是最好的解决scheme。 起初,我认为,因为Django的QuerySet.objects.order_by
方法接受多个参数,你可以很容易地链接它们:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
但是,它不会像你所期望的那样工作。 举例来说,首先是根据分数sorting的总统名单(select前五位以便阅读):
>>> auths = Author.objects.order_by('-score')[:5] >>> for x in auths: print x ... James Monroe (487) Ulysses Simpson (474) Harry Truman (471) Benjamin Harrison (467) Gerald Rudolph (464)
使用亚历克斯·马尔泰利的解决scheme,准确地提供排名前5名的人last_name
:
>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x ... Benjamin Harrison (467) James Monroe (487) Gerald Rudolph (464) Ulysses Simpson (474) Harry Truman (471)
现在联合order_by
调用:
>>> myauths = Author.objects.order_by('-score', 'last_name')[:5] >>> for x in myauths: print x ... James Monroe (487) Ulysses Simpson (474) Harry Truman (471) Benjamin Harrison (467) Gerald Rudolph (464)
正如你所看到的,它和第一个结果是一样的,这意味着它不能像你期望的那样工作。
这是一个允许closures分数的方法。
author_count = Author.objects.count() cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)] top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')
您可能以这种方式在top_authors中获得30多位作者,而min(30,author_count)
则是在您less于30位作者的情况下。