views:

112

answers:

2

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?

+1  A: 

Compare date in the view, and pass something like in_the_past (boolean) to the extra_context.

Or better add it to the model as a property.

@property
def is_past_due(self):
    if date.now() > self.date:
        result = True
    else:
        result = False
    return result

Then in the view:

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

Basicly the template is not the place for date comparsion IMO.

bx2
Yes, I agree that templates are not the place for date comparison, but in this situation it seemed so much more elegant. In any case, I ultimately implemented a method in my django Model, inPast(), that compares the date to the current date and returns True if it is in the past and false otherwise. This then gets called from the template. Your solution works just as well or better, I was just curious to know whether there was a way to do it in the template.
Herman
I don't think so :( Also from coding-style, and refactoring POV, it's much better to be able to reproduce `is_past_due` as property further in ie. other templates otherwise you'd have to copy-paste same template code over and over again.
bx2
If you'd really, really, really like to mess around and compare dates in the template you have to pass current date as extra_context and then use standard `if` tag, but this is not elegant solution..
bx2
A: 

You can always pass datetime.datetime.now (since django models use Python's standard datetime object).

Using render_to_response, you could do something like this (after importing datetime):

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

Now that you have access to "now" inside of the template, you can compare dates just like you did in your examples.

Furthermore, if you use RequestContext in your views - you will be able to add "now" as a context_processor if you need this in multiple files. This will add "now" to any template rendered with a RequestContext.

However, it is more realistic that you simply just get the list of records that are before now in your original queryset and avoid querying for useless data in the first place:

listing.objects.filter(date__lt=datetime.datetime.now())
monokrome
Filtering would be advisable in most situations, but in my situation this is not the desired effect: I have a list of items with certain release dates, and I would like to differentiate between items that have already been released and those that are yet to be released, but both are relevant to the search. For some reason the 'now' variable, as you proposed, did not work for me. I assumed the problem was the greater than comparison in the if statement, apparently that is not available in all versions of Django.
Herman
You need to have imported datetime with this code: import datetimeIf you used: from datetime import datetimeThen the proper method would be, datetime.now() instead of datetime.datetime.now()This should work in all versions of django. Which version are you using?
monokrome