如何在 django 中向 Case、When 条件添加排序
Posted
技术标签:
【中文标题】如何在 django 中向 Case、When 条件添加排序【英文标题】:How to add ordering to Case, When conditions in django 【发布时间】:2021-12-01 05:30:03 【问题描述】:有两个字段:start_date 和 end_date。 (日期字段)。
排序标准。
-
start_date 和 end_date 都是空值。 (start_date = Null,end_date = Null)
Start_date 最近和 end_date 为空值(start_date = not null,end_date = Null)
如果 start_date 和 end_date 都有值,则 end_date 最近(start_date = 非 Null,end_date = 非 Null)
如果 start_date 和 end_date 都有值,则 start_date 最近(start_date = 非 Null,end_date = 非 Null)
例如)我想要
start end
1. null null
2. null null
3. 2021-10-01 null
4. 2021-09-01 null
5. 2021-09-15 21-09-20
6. 2021-09-01 2021-09-20
7. 2021-09-01 2021-09-15
我试过了
Model.objects.annotate(
order1=Case(
When(Q(start_date__isnull=True) & Q(end_date__isnull=True), then=0),
When(Q(start_date__isnull=False) & Q(end_date__isnull=True), then=1), # how to order by start_date ??
When(Q(start_date__isnull=False) & Q(end_date__isnull=False), then=2), # how to order by end_date ??
output_field=IntegerField()
),
).order_by('order1')
结果
start end
1. null null
2. null null
3. 2021-09-01 null # change 3, 4
4. 2021-10-01 null
5. 2021-09-15 21-09-20
6. 2021-09-01 2021-09-20
7. 2021-09-01 2021-09-15
在 django 中如何解决复杂的订单?
【问题讨论】:
分享你的模型? 我没有共享模型,因为我不考虑除 start_date 和 end_date 之外的字段。 我自己找到了答案。从代码中可以看出,order1 只是一个注解。谢谢你:) 【参考方案1】:我找到了一种操作方法,虽然速度很慢。它没有经过完全测试。
Model.objects.annotate(
order1=Case(When(Q(start_date__isnull=True) & Q(end_date__isnull=True), then=1), default=0, output_field=IntegerField())
).annotate(
order2=Case(When(Q(start_date__isnull=False) & Q(end_date__isnull=True), then=Max('start_date')), output_field=DateField())
).annotate(
order3=Case(When(Q(start_date__isnull=False) & Q(end_date__isnull=False), then=Max('end_date')), output_field=DateField())
).order_by(
F('order1').desc(nulls_last=True), F('order2').desc(), F('order3').desc(), '-start_date'
)
我不认为这是完美的解决方案,但我分享它是因为它可以帮助某人。
如果有更好的方法,请分享。
【讨论】:
以上是关于如何在 django 中向 Case、When 条件添加排序的主要内容,如果未能解决你的问题,请参考以下文章