2010-09-26 59 views
33

我想将日期与Django中的当前日期进行比较,最好在模板中进行比较,但在呈现模板之前也可以这样做。如果日期已过,我想说“过去”,而如果是将来,我想给出日期。如何在Django中比较日期

我希望人们可以做这样的事情:

{% if listing.date <= now %} 
    In the past 
{% else %} 
    {{ listing.date|date:"d M Y" }} 
{% endif %} 

随着现在是今天的日期,但这不起作用。在Django文档中我找不到任何关于此的信息。任何人都可以提供一些建议

回答

72

在视图中比较日期,并将诸如in_the_past(boolean)之类的内容传递给extra_context。

或者最好将它作为属性添加到模型中。

from datetime import date 

@property 
def is_past_due(self): 
    return date.today() > self.date 

然后在视图:

{% if listing.is_past_due %} 
    In the past 
{% else %} 
    {{ listing.date|date:"d M Y" }} 
{% endif %} 

基本上模板不是日期比较IMO的地方。

+0

是的,我同意模板不是日期比较的地方,但在这种情况下,它看起来更优雅。无论如何,我最终在我的django模型中实现了一个方法inPast(),它将日期与当前日期进行比较,如果它在过去时返回True,否则返回false。然后从模板中调用。你的解决方案工作的更好或更好,我只是想知道是否有办法在模板中做到这一点。 – 2010-09-26 17:18:41

+2

我不这么认为:(同样来自编码风格和重构POV,能够在其他模板中进一步重现'is_past_due'作为属性更好,否则你必须复制粘贴相同的模板代码 – bx2 2010-09-26 17:20:53

+1

如果你真的真的想要在模板中混淆并比较日期,那么必须将当前日期作为extra_context传递,然后使用标准的if标记,但这不是优雅的解决方案。 – bx2 2010-09-26 17:23:10

0

您可以始终传递datetime.datetime.now(因为django模型使用Python的标准日期时间对象)。

使用选择render_to_response,你可以做这样的事情(进口日期时间后):

return render_to_response('template.html', {'now': datetime.datetime.now()}) 

现在你已经到“现在”的模板里面,你可以比较日期,就像你在做访问您的例子。此外,如果您在视图中使用RequestContext - 如果您需要在多个文件中使用它,则可以将“now”添加为context_processor。这会将“现在”添加到使用RequestContext呈现的任何模板中。

但是,它是更现实的,你只是刚刚获得的是以前,现在在你原来的查询集记录名单,并避免在第一时间查询无用的数据:

listing.objects.filter(date__lt=datetime.datetime.now()) 
+0

在大多数情况下,过滤将是明智的,但在我的情况下,这不是预期的效果:我有一个包含某些发布日期的项目列表,想要区分已发布的项目和尚未发布的项目,但都与搜索有关。出于某种原因,如您所提议的那样,“now”变量不适合我。假设这个问题比if语句中的比较大,显然这在所有版本的Django中都是不可用的。 – 2010-09-27 21:48:51

+0

你需要有与此代码进口日期时间: 进口日期时间 如果你使用: 从日期时间日期时间进口 然后正确的方法是,datetime.now()而不是datetime.datetime.now() 这应该适用于所有版本的django。你正在使用哪个版本? – monokrome 2010-10-18 23:16:06

9

我加date_now我上下文处理器列表。

所以在模板有一个名为“date_now”变量,它只是datetime.datetime.now()

请叫date_now上下文处理器在文件context_processors.py

import datetime 

def date_now(request): 
    return {'date_now':datetime.datetime.now()} 

而且在settings.py,修改CONTEXT_PROCESSORS包括它,在我的情况下,它

app_name.context_processors.date_now 
1

除了@ BX2有益的答案,如果你的领域是一个日期时间字段只需要调用d吃()函数模型DateTimeField字段:

from datetime import date 

@property 
def is_past_due(self): 
    if date.today() > self.date.date(): 
     return True 
    return False 
0

我发现这个问题,也有类似的问题。我希望显示信息,如果它只发生在过去。

在模板中使用Django的“timesince”标签我能解决我的问题。我并不是说它效率很高,但它适用于我。

模板:

{% if model_name.date_time|timesince >= "1 min" %} 
    <p>In the past</p> 
{% else %} 
    <p>{{ model_name.date_time }}</p> 
{% endif %} 
+0

这甚至不建议作为快速解决方案,因为您正在比较字符串。一天之后,你在比较''1天'> ='1分钟''这是'假',而你期待'真' – blacklwhite 2016-05-18 13:07:27

7

由于Django的1.8以下略难吃构造做的工作:

{% now "Y-m-d" as todays_date %} 
{% if todays_date < someday|date:"Y-m-d" %} 
    <h1>It's not too late!</h1> 
{% endif %} 

的hackish,但它避免了自定义标记或背景处理器的需要。