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

rub*_*eet 18 python mysql django orm

我有一个表'门票'与以下列

  • id - 主键 - 自动增量
  • title - varchar(256)
  • status - smallint(6) - 可以有1到5之间的任何值,由Django处理

当我要做的时候,SELECT *我想要status = 4顶部的行,其他记录将跟随它们.它可以通过以下查询来实现:

select * from tickets order by status=4 DESC
Run Code Online (Sandbox Code Playgroud)

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

Ofr*_*viv 20

q = Ticket.objects.extra(select={'is_top': "status = 4"})
q = q.extra(order_by = ['-is_top'])
Run Code Online (Sandbox Code Playgroud)

  • 我因为它的整洁而赞成它,但后来注意到文档中的一条注释说 .extra() 计划被弃用。这可以通过其他方式完成吗,例如使用注释?https://docs.djangoproject.com/en/1.10/ref/models/querysets/#extra (2认同)

小智 8

对于那些像我一样有需要的人现在偶然发现了这个并正在使用较新版本的 Django

from django.db.models import Case, When

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')
Run Code Online (Sandbox Code Playgroud)

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


Hem*_*egi 6

我在使用带有django的PostgresSql时这样做了.

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

Ticket.objects.annotate(
    relevancy=Count(Case(When(status=4, then=1)))
).order_by('-relevancy')
Run Code Online (Sandbox Code Playgroud)

它将从Ticket返回所有对象,但status = 4的票证将在开头.

希望有人会觉得它很有用.