【问题标题】:How to compare dates in Django templates如何比较 Django 模板中的日期
【发布时间】:2011-04-17 11:05:49
【问题描述】:

我想在 Django 中将日期与当前日期进行比较,最好在模板中进行比较,但也可以在渲染模板之前进行。如果日期已经过去,我想说“过去”,如果是将来,我想给出日期。

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

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

现在是今天的日期,但这不起作用。我在 Django 文档中找不到任何关于此的内容。谁能给点建议?

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    比较视图中的日期,并将in_the_past(布尔值)之类的内容传递给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 日期比较的地方。

    【讨论】:

    • 是的,我同意模板不是日期比较的地方,但在这种情况下,它看起来要优雅得多。无论如何,我最终在我的 django 模型中实现了一个方法 inPast(),它将日期与当前日期进行比较,如果是过去则返回 True,否则返回 false。然后从模板中调用它。您的解决方案效果一样好或更好,我只是想知道模板中是否有办法做到这一点。
    • 我不这么认为 :( 同样来自编码风格和重构 POV,最好能够在 ie 中将is_past_due 作为属性进一步复制。其他模板,否则你会有一遍又一遍地复制粘贴相同的模板代码。
    • 如果你真的,真的,真的很想在模板中搞乱和比较日期,你必须将当前日期作为 extra_context 传递,然后使用标准的if 标签,但这不是优雅的解决方案..
    • 很好的解决方案!在模型中创建属性并稍后在模板中使用它们是一个很好的解决方案。毕竟从更复杂的函数的角度来看,这是一个正确的解决方案!
    【解决方案2】:

    从 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,但它避免了对自定义标签或上下文处理器的需求。

    【讨论】:

    • Dirk++; Django--
    【解决方案3】:

    我将 date_now 添加到我的上下文处理器列表中。

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

    在文件 context_processors.py 中创建一个名为 date_now 的上下文处理器

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

    在 settings.py 中,修改 CONTEXT_PROCESSORS 以包含它,在我的例子中是

    app_name.context_processors.date_now
    

    【讨论】:

      【解决方案4】:

      除了@bx2 有益的答案,如果您的字段是日期时间字段,只需调用 date() 函数来模拟日期时间字段:

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

      编辑:我认为这可以缩小为:

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

      【讨论】:

        【解决方案5】:

        我相信实现这一点的最简单方法是在您的 views.py 中导入日期时间并将今天的日期作为上下文数据传递。

        context['today'] = datetime.date.today()
        

        然后在模板标签中你可以做这样的事情。

         {% if listing.date < today % }
        

        这样,如果您将对象列表作为上下文传递,您可以在 HTML 模板中输出时将过滤器应用于每一行。我有一个我已经过滤掉的项目列表,并在我显示它们时使用 Bootstrap 进行风格化。我想让过期日期脱颖而出,并且仅当我的日期之一小于今天的日期时才应用过滤。

        【讨论】:

          【解决方案6】:

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

          使用 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())
          

          【讨论】:

          • 在大多数情况下建议进行过滤,但在我的情况下,这不是预期的效果:我有一个具有特定发布日期的项目列表,我想区分已经发布的项目已发布和尚未发布,但两者都与搜索相关。出于某种原因,正如您提出的那样,“现在”变量对我不起作用。我认为问题在于 if 语句中的大于比较,显然这在所有版本的 Django 中都不可用。
          • 您需要使用以下代码导入日期时间: import datetime 如果您使用: from datetime import datetime 那么正确的方法是 datetime.now() 而不是 datetime.datetime.now() 这个应该适用于所有版本的 django。你用的是哪个版本?
          【解决方案7】:

          你可以有 2 个任务。

          1. 您必须使用 DetailView 显示对象。您可以通过使用将布尔值传递给模板的函数来解决此问题。但是,请记住,在 django 中,您无法将 SQL 数据库中的日期与datetime.datetime.now() 进行比较,因为第二个选项不包含时区信息。 使用django.utils.timezone.now()
          2. 您必须为 ListView 中的对象设置样式。然后我建议您使用将在模板中调用的自定义过滤器。
          @register.filter
          def compare_date(date):
             if not date:
                return False
             return date < timezone.now()
          

          【讨论】:

            【解决方案8】:

            我发现了这个问题并且遇到了类似的问题。如果它只发生在过去,我正在寻找显示信息。

            在模板中使用 Django 的“timesince”标签,我能够解决我的问题。我并不是说它有效,但它对我有用。

            在模板中:

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

            【讨论】:

            • 这甚至不推荐作为快速解决方案,因为您正在比较字符串。一天后,您正在比较 "1 day" &gt;= "1 min" 这是 False 而您期待 True
            猜你喜欢
            • 2018-09-25
            • 1970-01-01
            • 2021-02-12
            • 2013-03-18
            • 2021-12-31
            • 2013-04-06
            • 2013-05-19
            • 2010-12-25
            相关资源
            最近更新 更多