Django template - Is there a built-in way to get current date as type 'date' instead of type 'str'?

后端 未结 1 1076
一生所求
一生所求 2020-12-12 05:27

I know I can get the current date as a str in a Django template (using the template tag now), like this:

{% now \"Y-m-d\" as today_str %}


        
相关标签:
1条回答
  • 2020-12-12 05:40

    So, all my searching didn't yield a short solution. The answer to the question seems to be: no, there is no buit-in way to get the current date (or datetime) as a variable in the template.

    In case others are searching for this topic, I'll try to give a summary of the possible workarounds that I can up with and that were suggested by other users.


    1. I could pass a context variable to the template from my view. In class-based views that could look like this (it is even an example in the 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. I could create a custom context processor that loads that variable to every template. In class-based views that could look like this:

      # 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. I could create a custom template tag, like this:

      # 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()
      

      To be used like this:

      {% 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. I could also add a property (or even a cached_property) to the model:

      # 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. And last but not least, I could just do the processing in the view and add a property to the elements:

      # 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})
      
    0 讨论(0)
提交回复
热议问题