Django按日期排序,但最后有"无"?

Gar*_*nzo 45 django django-models django-queryset

我有一个工单的模型,有一个需要工作单的字段.要获得工作单列表,以及早期需要的工单,我这样做:

wo = Work_Order.objects.order_by('dateWORequired')

这很好用,但只有在该字段中实际存在值时才有效.如果没有必需的日期,则值为None.然后,工单的列表包含所有的None顶部,然后是正确顺序的剩余工单.

我怎样才能得到None底部的?

Ric*_*c W 44

Django 1.11将其添加为本机功能.这有点令人费解.记录在案.

只有一个字段,升序:

wo = Work_Order.objects.order_by(F('dateWORequired').asc(nulls_last=True))
Run Code Online (Sandbox Code Playgroud)

使用两个字段排序,均下降:

wo = Work_Order.objects.order_by(F('dateWORequired').desc(nulls_last=True), F('anotherfield').desc(nulls_last=True))
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 38

q = q.extra(select={
        'date_is_null': 'dateWORequired IS NULL',
    },
    order_by=['date_is_null','dateWORequired'],
)
Run Code Online (Sandbox Code Playgroud)

您可能需要 - 在order_by部分中的date_is_null之前 - 但这是您可以控制行为的方式.

  • 虽然这有效但它确实使用自定义SQL,如果可能的话,最好避免使用.在[Django:按位置忽略NULL的顺序]的接受答案中给出了不使用自定义SQL的替代方法(/sf/ask/366464661/) . (4认同)

Mar*_*ark 8

当问到这个问题时,这是不可用的,但是自从Django 1.8以来我认为这是最好的解决方案:

from django.db.models import Coalesce, Value
long_ago = datetime.datetime(year=1980, month=1, day=1)
Work_Order.objects.order_by('dateWORequired')
MyModel.objects.annotate(date_null=
    Coalesce('dateWORequired', Value(long_ago))).order_by('date_null')
Run Code Online (Sandbox Code Playgroud)

Coalesce选择第一个非空值,因此您创建一个date_null按订单排序的值,该值仅为dateWORequired,但null很久以前就被日期替换.