Как сравнить даты в Django
Я хотел бы сравнить дату с текущей датой в Django, желательно в шаблоне, но это также можно сделать перед отображением шаблона. Если дата уже прошла, я хочу сказать "В прошлом", а если это будет в будущем, я хочу указать дату.
Я надеялся, что можно сделать что-то вроде этого:
{% if listing.date <= now %}
In the past
{% else %}
{{ listing.date|date:"d M Y" }}
{% endif %}
С сегодняшней датой, но это не сработает. Я не мог найти ничего об этом в документах Django. Может ли кто-нибудь дать совет?
Ответы
Ответ 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 %}