本文介绍 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')
如果 Blog
有 ordering = ['name']
,那么第一个查询集将等同于:
Entry.objects.order_by('blog__name')
您还可以通过在表达式上调用
或 asc()
来按查询表达式排序:desc()
Entry.objects.order_by(Coalesce('summary', 'headline').desc())
和 asc()
具有控制空值排序方式的参数( desc()
nulls_first
和 nulls_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
可能有多个排序数据;每个带有多个 children
的 Event
将多次返回到 order_by()
创建的新 QuerySet
中。换句话说,在QuerySet
上使用order_by()
可能会返回比您开始工作时更多的项目——这可能既不是预期的也不是有用的。
因此,在使用multi-valued 字段对结果进行排序时要小心。如果您可以确定您排序的每件商品只有一个排序数据,那么这种方法应该不会出现问题。如果没有,请确保结果符合您的预期。
没有办法指定排序是否应该区分大小写。关于区分大小写,Django 将对结果进行排序,但是您的数据库后端通常会对其进行排序。
您可以使用
将字段转换为小写,这将实现 case-consistent 排序:Lower
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
字段不是唯一的,则按它排序并不能保证具有相同名称的对象总是以相同的顺序出现。
相关用法
- Python Django QuerySet.only用法及代码示例
- Python Django QuerySet.select_related用法及代码示例
- Python Django QuerySet.union用法及代码示例
- Python Django QuerySet.latest用法及代码示例
- Python Django QuerySet.values用法及代码示例
- Python Django QuerySet.intersection用法及代码示例
- Python Django QuerySet.get用法及代码示例
- Python Django QuerySet.none用法及代码示例
- Python Django QuerySet.exclude用法及代码示例
- Python Django QuerySet.get_or_create用法及代码示例
- Python Django QuerySet.update_or_create用法及代码示例
- Python Django QuerySet.prefetch_related用法及代码示例
- Python Django QuerySet.first用法及代码示例
- Python Django QuerySet.annotate用法及代码示例
- Python Django QuerySet.dates用法及代码示例
- Python Django QuerySet.values_list用法及代码示例
- Python Django QuerySet.select_for_update用法及代码示例
- Python Django QuerySet.bulk_update用法及代码示例
- Python Django QuerySet.in_bulk用法及代码示例
- Python Django QuerySet.defer用法及代码示例
- Python Django QuerySet.aggregate用法及代码示例
- Python Django QuerySet.reverse用法及代码示例
- Python Django QuerySet.count用法及代码示例
- Python Django QuerySet.exists用法及代码示例
- Python Django QuerySet.explain用法及代码示例
注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.db.models.query.QuerySet.order_by。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。