Подтвердить что ты не робот

Как сравнить даты в Django

Я хотел бы сравнить дату с текущей датой в Django, желательно в шаблоне, но это также можно сделать перед отображением шаблона. Если дата уже прошла, я хочу сказать "В прошлом", а если это будет в будущем, я хочу указать дату.

Я надеялся, что можно сделать что-то вроде этого:

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

С сегодняшней датой, но это не сработает. Я не мог найти ничего об этом в документах Django. Может ли кто-нибудь дать совет?

4b9b3361

Ответ 1

Сравнить дату в представлении и передать что-то вроде 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.

Ответ 2

Я добавил 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

Ответ 3

По состоянию на Django 1.8 следующая слегка отвратительная конструкция выполняет задание:

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

Hackish, но он избегает необходимости создания настраиваемого тега или процессора контекста.

Ответ 4

дополнение к @bx2 полезному ответу, если ваше поле является полем даты и времени, просто вызывайте функцию date() для моделей datetimefield:

from datetime import date

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

Ответ 5

Вы всегда можете передать datetime.datetime.now(поскольку модели django используют стандартный datetime-объект Python).

Используя render_to_response, вы можете сделать что-то вроде этого (после импорта datetime):

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

Теперь, когда у вас есть доступ к "сейчас" внутри шаблона, вы можете сравнивать даты так же, как в своих примерах.

Кроме того, если вы используете RequestContext в своих представлениях, вы сможете добавить "сейчас" в качестве контекстного_процессора, если вам это нужно в нескольких файлах. Это добавит "сейчас" к любому шаблону, создаваемому с помощью RequestContext.

Однако, более реалистично, что вы просто просто получаете список записей, которые были до этого в вашем исходном наборе запросов, и избегайте запросов на бесполезные данные в первую очередь:

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

Ответ 6

Я нашел этот вопрос и имел аналогичную проблему. Я искал информацию, если бы это произошло только в прошлом.

Использование тега Django "timesince" в шаблоне я смог решить мою проблему. Я не говорю об этом эффективно, но это работает для меня.

В шаблоне:

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