代码之家  ›  专栏  ›  技术社区  ›  Ralf

Django模板-是否有一种内置的方法可以将当前日期作为'date'类型而不是'str'类型获取?

  •  0
  • Ralf  · 技术社区  · 7 年前

    str 在Django模板中(使用 template tag now ),如下所示:

    {% now "Y-m-d" as today_str %}
    <p>{{ today_str }}</p>
    

    但我不能用它来做比较:

    {% now "Y-m-d" as today_str %}
    
    {% for elem in object_list %}
        {% if elem.date < today_str %}        {# WRONG: this compares 'date' and 'str' #}
            <p>{{ elem.pk }} before today</p>
            {# do some other rendering #}
        {% endif %}
    {% endfor %}
    

    可能的解决方案:

    1. 我知道我可以将上下文变量传递给模板,但在我看来它需要代码:

      # in my class-based-view in 'views.py'
      def get_context_data(self, **kwargs):
          ctx = super().get_context_data(**kwargs)
          ctx['today'] = timezone.now()
          return ctx
      
    2. 或者我可以创建一个自定义模板标记,但这是更多的额外代码。

    如你所见,我有我的问题的解决办法,但我想知道是否有一个内置的方式来获得当前的 date (或 datetime

    1 回复  |  直到 7 年前
        1
  •  6
  •   Ralf    7 年前

    所以,我所有的搜索都没有给出一个简短的解决方案。这个问题的答案似乎是:不,没有内置的方法来获取当前日期(或datetime)作为模板中的变量。

    如果其他人正在搜索这个主题,我将尝试给出一个可能的解决方法的摘要,我可以想出和其他用户建议。


    1. 我可以从视图中将上下文变量传递给模板。在基于类的视图中,可以这样看(这甚至是 docs ):

      # file 'my_app/views.py'
      from django.utils import timezone as tz
      from django.views.generic import ListView
      
      class MyView(ListView)
          ...
      
          def get_context_data(self, **kwargs):
              ctx = super().get_context_data(**kwargs)
      
              now = tz.now()
              ctx['now'] = now
              ctx['today'] = tz.localtime(now).date()
      
              return ctx
      
    2. 我可以创建一个自定义 context processor 将该变量加载到每个模板。在基于类的视图中,可以如下所示:

      # file 'context_processors.py'
      from django.utils import timezone as tz
      
      def now_and_today(request):
          now = tz.now()
          return {
              'now': now,
              'today': tz.localtime(now).date(),
          }
      
      # file 'settings.py'
      ...
      TEMPLATES = [
          {
              ...
              'OPTIONS': {
                  'context_processors': [
                      ...
                      'context_processors.today_and_now',
                  ],
              },
          },
      ]
      ...
      
    3. custom template tag ,如下所示:

      # file 'my_app/custom_template_tags/custom_time_tags.py'
      from django.utils import timezone as tz
      from django import template
      register = template.Library()
      
      @register.simple_tag
      def get_now(request):
          return tz.now()
      
      @register.simple_tag
      def get_today(request):
          return tz.localtime(tz.now()).date()
      

      这样使用:

      {% load 'custom_time_tags' %}
      
      {% get_today as today %}
      {% for per in person_list %}
          {% if per.brith_date > today %}
              <p>{{ per.name }} is from the future!!<p>
          {% endif %}
      {% endfor %}
      
    4. 我还可以添加一个属性(甚至一个 cached_property )对于模型:

      # file 'models.py'
      from django.db import models
      from django.utils import timezone as tz
      from django.utils.functional import cached_property
      
      class Person(models.Model):
          ...
      
          @cached_property
          def is_from_future(self):
              # careful: for long-lived instances do not use 'cached_property' as
              # the time of 'now' might not be right later
              if self.birth_date > tz.localtime(tz.now()).date():
                  return True
      
              return False
      
    5. # file 'my_app/views.py'
      from django.utils import timezone as tz
      
      def person_list(request):
          today = tz.localtime(tz.now()).date()
      
          person_list = []
          for p in Person.objects.all():
              p.is_from_future = self.birth_date > today
              person_list.append(p)
      
          return render(request, 'some_template.html', {'person_list': person_list})