排序查询集的好方法?-姜戈

我要做的是:

  • 获得得分最高的30位作者(Author.objects.order_by('-score')[:30])

  • last_name排序作者


有什么建议吗?

176386 次浏览

关于什么

import operator


auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))

在 Django 1.4和更新的版本中,您可以通过提供多个字段进行订购。
参考文献: < a href = “ https://docs.djangoproject.com/en/dev/ref/model/querysets/# order-by”rel = “ norefrer”> https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

Order _ by (* fields)

默认情况下,由 QuerySet返回的结果按照模型 Meta 中的 ordering选项给出的排序元组进行排序。您可以使用 order_by方法在每个 QuerySet 的基础上重写它。

例如:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

上面的结果将按 score降序排列,然后按 last_name升序排列。"-score"前面的负号表示降序。升序是暗示的。

这里有一种方法,允许平局的截止得分。

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 _ author 中获得超过30个作者,如果作者少于30个,那么 min(30,author_count)就在那里。

我只是想说明内置的解决方案(仅限 SQL)并不总是最好的。起初,我认为因为 Django 的 QuerySet.objects.order_by方法接受多个参数,所以可以很容易地将它们链接起来:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

但是,它并不像你期望的那样工作。举个例子,首先是一个按分数排序的总统列表(选择前5名以便阅读) :

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

使用亚历克斯•马特利(Alex Martelli)的解决方案,该方案准确地提供了按 last_name排序的前5名:

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

正如你所看到的,它和第一个结果是一样的,这意味着它并不像你期望的那样工作。