django - Django-按字段排序,除非它为空,然后使用另一个
问题描述
可以说我有以下模型:
class MyModel(models.Model):
name = models.CharField(max_length=255)
date_1 = models.DateField(null=True, blank=True)
date_2 = models.DateField(null=True, blank=True)
每个模型至少有 1 个日期字段。我想做的是按以下顺序订购-如果模型有date_1
,请按以下顺序订购date_1
。如果没有date_1
,请改为订购date_2
。做这样的事情:
MyModel.objects.all().order_by('date_1', 'date_2')
会将所有 null date_1 值粘贴到末尾。而我想要“交错”。例如,我想要以下输出(json 格式):
[
{"id": 1, "date_1": "2020-02-01", "date_2": null},
{"id": 4, "date_1": null, "date_2": 2020-02-02}, # orders by date_2 as there is no date_1
{"id": 2, "date_1": "2020-02-03", "date_2": "2020-02-01"}, # orders by date_1, ignores date_2
{"id": 3, "date_1": "2020-02-04", "date_2": null},
]
这可能与django ORM有关吗?
解决方案
您可以使用Coalesce
表达式 [Django-doc]进行注释,然后对该字段进行排序:
from django.db.models.functions import Coalesce
MyModel.objects.annotate(
date=Coalesce('date1', 'date2')
).order_by('date')
甚至更短:您可以Coalesce
直接订购:
from django.db.models.functions import Coalesce
MyModel.objects.order_by(Coalesce('date1', 'date2').asc())