Шаблон Django - есть ли встроенный способ получить текущую дату как тип 'date' вместо типа 'str'? - PullRequest
0 голосов
/ 12 сентября 2018

Я знаю, что могу получить текущую дату как str в шаблоне Django (используя тег шаблона 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 Ответ

0 голосов
/ 14 сентября 2018

Итак, все мои поиски не дали краткого решения.Похоже, что ответ на этот вопрос таков: нет, нет способа получить текущую дату (или дату / время) в качестве переменной в шаблоне.

В случае, если другие люди ищут эту тему, яЯ постараюсь дать краткую информацию о возможных обходных путях, которые я могу использовать, и которые были предложены другими пользователями.


  1. Я мог бы передать переменную контекста в шаблон из моегоПосмотреть.В представлениях на основе классов, которые могут выглядеть следующим образом (это даже пример в документах ):

    # 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. Я мог бы создать пользовательский контекстный процессор , который загружает эту переменную в каждый шаблон.В представлениях на основе классов это может выглядеть следующим образом:

    # 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. Я мог бы создать пользовательский тег шаблона , например:

    # 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})
    
...