Django ORM 可以对列的特定值执行 ORDER BY 吗?

Posted

技术标签:

【中文标题】Django ORM 可以对列的特定值执行 ORDER BY 吗?【英文标题】:Can Django ORM do an ORDER BY on a specific value of a column? 【发布时间】:2011-01-11 16:36:12 【问题描述】:

我有一个包含以下列的表格“门票”

id - 主键 - 自动递增 标题 - varchar(256) 状态 - smallint(6) - 可以有 1 到 5 之间的任何值,由 Django 处理

当我执行SELECT * 时,我希望顶部带有status = 4 的行,其他记录将跟随它们。可以通过以下查询来实现:

select * from tickets order by status=4 DESC

这个查询可以通过 Django ORM 执行吗?应该将哪些参数传递给QuerySet.order_by() 方法?

【问题讨论】:

你不是在排序,你是在过滤(SQL WHERE 子句)。 @stefanw - 如果只想要 status=4 的记录,这将被称为过滤,我不想要。 【参考方案1】:

对于那些有需要的人,就像我一样,现在偶然发现并正在使用更新版本的 django

Ticket.objects.annotate(
            relevancy=Case(When(status=4, then=1), When(status=3, then=2), When(status=2, then=3), output_field=IntegerField())
        ).order_by('-relevancy')

使用 Count() 将返回 1 或 0,具体取决于您的案例是否被发现。如果按几个状态订购则不理想

【讨论】:

【参考方案2】:

我在 django 中使用 PostgresSql 时这样做了。

from django.db.models import Case, Count, When

Ticket.objects.annotate(
    relevancy=Count(Case(When(status=4, then=1)))
).order_by('-relevancy')

它将返回 Ticket 中的所有对象,但 status = 4 的门票将在开头。

希望有人会觉得它有用。

【讨论】:

【参考方案3】:
q = Ticket.objects.extra(select='is_top': "status = 4")
q = q.extra(order_by = ['-is_top'])

【讨论】:

我赞成它的简洁性,但后来注意到文档中的一条注释说 .extra() 计划被弃用。这可以通过其他方式完成吗,例如带注释? docs.djangoproject.com/en/1.10/ref/models/querysets/#extra

以上是关于Django ORM 可以对列的特定值执行 ORDER BY 吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Linux 工具根据另一列的 id 对列的值求和

如何使用 Django ORM 排除列的多个值?

如何选择第 n 列,并在 BigQuery 中对列的选择进行排序

根据来自不同列的 2 个其他值对列的值求和

使用子查询对列的值求和

SonataAdminBundle 如何在列表视图中对列的值求和