我有两个定义的Django模型:
Item =具有到期日期的一组项目。 事件=一组具有开始和结束日期的事件。
我的目的是,当显示该项目时,将根据该项目是否在下一个事件的结束日期之后但在下一个事件的结束日期之前到期来有条件地格式化其到期日期(因此请警告到期时间)。
问题就变成了,如何最好地管理这一壮举?
如果我直接访问数据库,我将使用子查询来获取将来的最小结束日期,然后将其与if进行比较,以交换格式。
从研究中,我得出的结论是,最好在视图逻辑中解决此问题,而不是尝试在两个模型中设置一个方法,但我不知道如何最好地将其拼接在一起因此我可以从Item模型返回我的最小将来日期和itemlist对象的值。
当前视图在此阶段非常简单(稍后将有更多过滤选项):
def itemlist(request):
item_list = Item.objects.all
return render(request, "itemlist.html", {'item_list': item_list})
但是我看不到一种轻松返回与我在直接SQL中所做的类似的django等效方式的方法:
select item from items where status != expired and expiry_date <= (select min(end_date) from events where end_date >= getdate() )
编辑:自从我写了这篇文章以来,我已经意识到我想要的比较要复杂一些,因为它不是最短日期,而是最短日期。
对于项A,有效期为19/05/19
事件A:结束日期19/04/25 事件B:end_date 10/05/19
我需要做的是在读回项目列表时检查事件,看到项目A的到期日期在下一个事件之后。事件A的结束日期,但在事件B的event.end_date之前,因此设置在模板的到期日期显示上使用条件格式的标志。
最终,我想,愿望清单还应针对每个项目说:“如果列表中有一个事件在其过期时间之后发生变化,那么我可以在该项目过期之前更新该事件是什么?”
答案 0 :(得分:1)
我无法从您的描述中完全理解您的requiremets,但是您也可以在Django中使用子查询。如果您这样过滤:
now = datetime.datetime.utcnow()
Item.objects.annotate(last_event_time=Subquery(Event.objects.filter(end_date__gt=now).values('end_date').order_by('-end_date')[:1]))
结果查询集中的每个项目都将具有 last_event_time 字段,该字段将保留最新的事件 end_date 字段。
您还可以使用F表达式将此字段用于进一步过滤:
Item.objects.annotate(last_event_time=Subquery(Event.objects.filter(end_date__gt=now).values('end_date').order_by('-end_date')[:1])).filter(expiry_date__lte=F('last_event_time'))