首页 > 解决方案 > 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有关吗?

标签: django

解决方案


您可以使用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())

推荐阅读