当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python Django QuerySet.order_by用法及代码示例


本文介绍 django.db.models.query.QuerySet.order_by 的用法。

声明

order_by(*fields)

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

例子:

Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

上面的结果将按 pub_date 降序排列,然后按 headline 升序排列。 "-pub_date"前面的负号表示descending顺序。升序是隐含的。要随机排序,请使用 "?" ,如下所示:

Entry.objects.order_by('?')

注意:order_by('?') 查询可能既昂贵又缓慢,具体取决于您使用的数据库后端。

要按不同模型中的字段排序,请使用与跨模型关系查询时相同的语法。也就是说,字段的名称后跟双下划线 (__),然后是新模型中的字段名称,依此类推,以加入任意数量的模型。例如:

Entry.objects.order_by('blog__name', 'headline')

如果您尝试按与另一个模型相关的字段排序,Django 将使用相关模型的默认排序,或者如果没有指定 Meta.ordering ,则按相关模型的主键排序。例如,由于 Blog 模型没有指定默认排序:

Entry.objects.order_by('blog')

…等同于:

Entry.objects.order_by('blog__id')

如果 Blogordering = ['name'] ,那么第一个查询集将等同于:

Entry.objects.order_by('blog__name')

您还可以通过在表达式上调用 asc() desc() 来按查询表达式排序:

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

asc() desc() 具有控制空值排序方式的参数( nulls_firstnulls_last )。

如果您还使用 distinct() ,则在相关模型中按字段排序时要小心。请参阅 distinct() 中的注释,了解相关模型排序如何改变预期结果。

注意

允许指定 multi-valued 字段来对结果进行排序(例如, ManyToManyField 字段,或 ForeignKey 字段的反向关系)。

考虑这种情况:

class Event(Model):
   parent = models.ForeignKey(
       'self',
       on_delete=models.CASCADE,
       related_name='children',
   )
   date = models.DateField()

Event.objects.order_by('children__date')

在这里,每个 Event 可能有多个排序数据;每个带有多个 childrenEvent 将多次返回到 order_by() 创建的新 QuerySet 中。换句话说,在QuerySet 上使用order_by() 可能会返回比您开始工作时更多的项目——这可能既不是预期的也不是有用的。

因此,在使用multi-valued 字段对结果进行排序时要小心。如果您可以确定您排序的每件商品只有一个排序数据,那么这种方法应该不会出现问题。如果没有,请确保结果符合您的预期。

没有办法指定排序是否应该区分大小写。关于区分大小写,Django 将对结果进行排序,但是您的数据库后端通常会对其进行排序。

您可以使用 Lower 将字段转换为小写,这将实现 case-consistent 排序:

Entry.objects.order_by(Lower('headline').desc())

如果您不希望对查询应用任何排序,甚至是默认排序,请不带参数调用 order_by()

您可以通过检查 QuerySet.ordered 属性来判断查询是否已排序,如果QuerySet 已以任何方式排序,则该属性将为True

每个 order_by() 调用将清除任何先前的排序。例如,此查询将按 pub_date 而不是 headline 排序:

Entry.objects.order_by('headline').order_by('pub_date')

警告

排序不是免费的操作。您添加到排序中的每个字段都会对您的数据库产生成本。您添加的每个外键也将隐式包含其所有默认排序。

如果查询未指定排序,则以未指定的顺序从数据库返回结果。仅当按一组唯一标识结果中每个对象的字段进行排序时,才能保证特定的排序。例如,如果 name 字段不是唯一的,则按它排序并不能保证具有相同名称的对象总是以相同的顺序出现。

相关用法


注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.db.models.query.QuerySet.order_by。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。