我有一个模型票,里面有一个金额。我试图在最近的到期日制作消费票。但如果我按date_expire
订购,它会将date_expire=None
模型移到顶部。但date_expire=None
意味着该票没有时间限制,应该在所有票之后使用,这是有时间限制的。
我的代码:
ticket = Tickets.objects.filter(
sum__gte=0,
date_expire__gte=timezone.now(),
user_id=user.id,
burned=False
).order_by(
'date_expire'
).first()
我可以尝试用带lambda键的sorted func来排序,但是我认为在orm中有更好的方法来完成
UPD
我想我找到了一个解决方案。现在我的代码看起来像:
ticket = Tickets.objects.filter(
sum__gte=0,
date_expire__gte=timezone.now(),
user_id=user.id,
burned=False
).annotate(
has_date=Func(F('date_expire'), Value(None), function='IFNULL')
).order_by(
'-has_date',
'date_expire'
).first()
我使用QuerySet
的annotate
函数生成一个新值has_date
,该值使用SQL函数IFNULL,如果字段date_expire
为NULL
,则返回True
。
查询中的SQL字段必须如下所示:
IFNULL("tickets"."date_expire", NULL) AS "has_date"
然后我首先按-has_date
排序,将所有具有True
值的对象移动到False
值之下。
也许有一个更好的方法来做到这一点,但这种方法对我的想法有效。
2条答案
按热度按时间muk1a3rh1#
您可以将
F
表达式与nulls_first
或nulls_last
一起使用。请查看django文档中的使用F()对空值进行排序。在您的情况下:
pgvzfuti2#
可能不是官方的解决方案:
一种方法是引入一个表示上限值的值。因此,不要为date_expire使用None,而是使用1000年后的日期,如
12/31/3000
。这样,该日期总是晚于当前日期。