How to compare dates in Django templates

Viewed 75650

I would like to compare a date to the current date in Django, preferably in the template, but it is also possible to do before rendering the template. If the date has already passed, I want to say "In the past" while if it is in the future, I want to give the date.

I was hoping one could do something like this:

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

With now being today's date, but this does not work. I couldn't find anything about this in the Django docs. Can anyone give some advice?

9 Answers

I added date_now to my list of context processors.

So in the template there's a variable called "date_now" which is just datetime.datetime.now()

Make a context processor called date_now in the file context_processors.py

import datetime

def date_now(request):
    return {'date_now':datetime.datetime.now()}

And in settings.py, modify CONTEXT_PROCESSORS to include it, in my case it's

app_name.context_processors.date_now

I believe the easiest way to achieve this is by importing datetime in your views.py and passing today's date as context data.

context['today'] = datetime.date.today()

Then in the template tags you could do something like this.

 {% if listing.date < today % }

This way if you are passing a list of objects as context, you can apply the filter to each line as you output it in the HTML template. I had a list of items that I had filtered out and was using Bootstrap to stylize as I displayed them. I wanted to make overdue dates stand out and applied the filtering only if one of my dates was less than today's date.

You can have 2 tasks.

  1. You must show the object using DetailView. You can solve this problem by using a function that passes a boolean value to the template. However, keep in mind that in django you cannot compare a date from a SQL database with datetime.datetime.now(), since the second option does not contain time zone information. Use django.utils.timezone.now().
  2. You must style the object from the ListView. Then I advise you to use a custom filter that you will call in the template.
@register.filter
def compare_date(date):
   if not date:
      return False
   return date < timezone.now()

If you use Django, you could use the bellow code(https://stackoverflow.com/a/3798865/17050678). In your models.py

@property
def is_past_due(self):
    today = datetime.datetime.today()
    return today > self.start_date

But it will take an error to you. like this:

can't compare offset-naive and offset-aware datetimes

So you should take the timezone type like the bellow.

import pytz
@property
def is_past_due(self):
    today =     datetime.datetime.today().astimezone(pytz.timezone('Asia/Tokyo'))
    return today > self.start_date

Then you could compare it in your template.

{% if schedule.is_past_due %}
/*your code here*/
{% endif %}
Related