首页 文章

Django:通过评估日期是否为空来排序

提问于
浏览
1

在Django中,是否可以通过字段是否为None来排序,而不是字段本身的值?

我知道我可以将QuerySet发送到python sorted() ,但是我想将它保存为QuerySet以便后续过滤 . 所以,我更喜欢在QuerySet中订购 .

例如,我有一个termination_date字段,我想首先排序没有termination_date的字段,然后我想通过一个不同的字段排序,比如last_name,first_name .

这是可能的还是我坚持使用 sorted() 然后不得不使用包含的ID执行一个全新的查询并在新的QuerySet上运行 sorted() ?我可以做到这一点,但是不想浪费开销并使用QuerySet的优点,直到评估它们才会运行 .

翻译,如何从Django获取此SQL,假设我的应用程序是 employee ,我的模型是 Employee ,它有三个字段'first_name (varchar)','last_name (varchar)'和'termination_date (date)':

SELECT
    "employee_employee"."last_name",
    "employee_employee"."first_name",
    "employee_employee"."termination_date"

FROM "employee_employee"

ORDER BY
    "employee_employee"."termination_date" IS NOT NULL,
    "employee_employee"."last_name",
    "employee_employee"."first_name"

2 回答

  • 1

    光谱' answer works fine, but it only orders your records by '是否为零' . 有一种较短的方式可以让您在日期订购中的任何地方放置空日期 - Coalesce

    from django.db.models import Value
    from django.db.models.functions import Coalesce
    
    wayback = datetime(year=1, month=1, day=1)  # or whatever date you want
    MyModel.objects
           .annotate(null_date=Coalesce('date_field', Value(wayback)))
           .order_by('null_date')
    

    这将基本上按字段 'date_field' 排序,所有带有 date_field == None 的记录将按顺序排列,就像它们具有日期 wayback 一样 . 这与PostgreSQL完美配合,但可能需要在MySQL中进行一些原始的sql转换,如documentation中所述 .

  • 1

    您应该可以通过query expressions订购,如下所示:

    from django.db.models import IntegerField, Case, Value, When
    
    MyModel.objects.all().order_by(
        Case(
            When(some_field=None, then=Value(1)),
            default=Value(0),
            output_field=IntegerField(),
        ).asc(),
        'some_other_field'
    )
    

    我不能在这里测试所以它可能需要一点摆弄,但是这应该在具有 some_field 的行之后放置具有NULL some_field 的行 . 每组行应按 some_other_field 排序 .

    当然,CASE / WHEN比你提出的问题要麻烦一些,但我不知道如何让Django ORM输出 . 也许别人会有更好的答案 .

相关问题