在Django项目开发中,查询集排序是非常常见的需求,比如按发布时间倒序展示文章列表、按价格升序展示商品信息等,正确设置排序规则才能让数据符合用户的查看习惯。

Django查询集排序的基础方法
Django查询集提供了order_by()方法来实现排序功能,该方法接收排序字段作为参数,返回按指定字段排序后的新查询集,不会修改原有查询集。
单字段排序
单字段排序是最基础的场景,只需要传入对应的模型字段名即可。如果需要升序排序,直接传字段名;如果需要降序排序,在字段名前加负号。
假设我们有一个文章模型Article,包含title、publish_time、read_count三个字段,下面是单字段排序的示例代码:
# 按发布时间升序排序(默认升序)
articles_asc = Article.objects.order_by('publish_time')
# 按发布时间降序排序
articles_desc = Article.objects.order_by('-publish_time')
# 按阅读量升序排序
articles_by_read = Article.objects.order_by('read_count')多字段排序
当单个字段无法完全区分数据顺序时,可以使用多字段排序,order_by()方法支持传入多个字段参数,排序优先级按照参数传入的顺序依次降低。
比如先按发布时间降序排序,发布时间相同的再按阅读量降序排序,代码如下:
# 多字段排序:先按发布时间降序,再按阅读量降序
articles_multi = Article.objects.order_by('-publish_time', '-read_count')排序的常见注意事项
默认排序与自定义排序的优先级
如果在模型Meta类中设置了ordering属性,查询集默认会按照该规则排序,此时如果调用order_by()方法,自定义排序会覆盖默认排序规则。
模型默认排序设置示例:
class Article(models.Model):
title = models.CharField(max_length=100)
publish_time = models.DateTimeField()
read_count = models.IntegerField()
class Meta:
# 默认按发布时间降序排序
ordering = ['-publish_time']如果此时执行Article.objects.order_by('read_count'),则会按照阅读量升序排序,忽略默认的发布时间排序规则。
避免无效排序字段
传入order_by()的字段必须是模型存在的字段,或者是在查询中定义的 annotate 字段,否则会抛出数据库异常。
比如给Article模型添加阅读量等级标注后再排序:
from django.db.models import Case, When, Value, IntegerField
# 给文章添加阅读量等级:read_count>1000为3,500-1000为2,其余为1
articles = Article.objects.annotate(
read_level=Case(
When(read_count__gt=1000, then=Value(3)),
When(read_count__gte=500, then=Value(2)),
default=Value(1),
output_field=IntegerField()
)
).order_by('-read_level', '-publish_time')排序对查询集性能的影响
如果排序的字段没有建立索引,当数据量较大时,排序操作会消耗较多的数据库资源,建议在常用的排序字段上建立索引,提升排序效率。
给publish_time字段添加索引的模型定义示例:
class Article(models.Model):
title = models.CharField(max_length=100)
# 给发布时间字段添加索引,提升排序性能
publish_time = models.DateTimeField(db_index=True)
read_count = models.IntegerField()
class Meta:
ordering = ['-publish_time']排序结果验证
可以通过打印查询集的SQL语句,或者直接输出查询结果的字段值,验证排序是否符合预期。
# 打印查询集对应的SQL语句,查看排序规则
print(articles_multi.query)
# 输出排序后的文章发布时间和阅读量,验证顺序
for article in articles_multi:
print(f"标题:{article.title},发布时间:{article.publish_time},阅读量:{article.read_count}")只要正确掌握order_by()方法的使用规则,注意排序字段的有效性和性能优化,就能确保Django查询集的数据按照预期顺序展示。