Reputation: 11
I'm using the Django templating language to output information on recent visitor's actions on a page.
The goal is to create a ifequal conditional statement to output a list showing the time since action for the last 5 actions. For anything that shows "0 minutes" we'd like to show "Less than a minute ago".
Right now it looks like the ifequal conditional statement isn't working for me.
I've tried the following:
Appreciate any help or advice you can give!
{% for a in page.recent_actions | slice:":5" %}
{% with j=a.created_at %}
{% ifequal j|timesince "0 minutes" %}
Less than a minute ago
{% else %}
{{ j|timesince }}
{% endifequal %}
{% endwith %}
{% endfor %}
Upvotes: 1
Views: 2545
Reputation: 1280
This is because the "0 minutes" returned by timesince/timeuntil has a non-breaking space in it, so it is not equal to the literal you have. (look at its implementation in django.utils.timesince.py
One option is to write a custom tag that takes advantage of timesince/timeuntil but compares a string with non-breaking space as those functions return:
from django import template
from django.utils.html import avoid_wrapping
from django.utils.translation import ugettext
from django.utils.timesince import timeuntil
register = template.Library()
@register.filter("is_past", is_safe=False)
def is_past(value, arg=None):
"""Returns true if a timestamp is in the past."""
if not value:
return False
try:
return timeuntil(value, arg) == avoid_wrapping(ugettext('0 minutes'))
except (ValueError, TypeError):
return False
Upvotes: 1
Reputation: 11
Thanks @AJ-Slater for the answer, it helped to see that it was better to be comparing datetimes instead of the output from the filters. We tried using the "sub" math filter which didn't work with this particular CRM, but what did work was {% ifequal a.created_at|timesince a.created_at|timeuntil %}
for the ifequal statement.
Upvotes: 0
Reputation: 61
{% ifequal a b %}
appears to be deprecated in django templates. The use of {% if a == b %}
is preferred.
The timesince filter requires a datetime type as input. For instance:
{{ created_dttm.strftime("%Y-%m-%d %H:%M:%S") }}
will output "2015-02-09 11:52:09"
{{ created_dttm|timesince }}
will output "0 minutes"
Ergo, if a.created_at
is a datetime, as would be appropriate for using the timeslice filter you might be better off comparing that datetime in the conditional rather than comparing a string. e.g.
{% if datetime.datetime.now() - datetime.timedelta(minutes=1) < j %}
Less than a minute ago
{% else %}
{{ j|timesince }}
{% endif %}`
if a.created_at
is really a string, as you allude to in your question, then using the timesince filter is inappropriate. I'd try to see if {% if a.created_at == "0 minutes" %}
.
Also storing datetimes as relative strings like "5 minutes" outside the presentation layer is probably not the greatest design. Consider using datetimes instead and converting to strings only in your presentation layer.
python dates and time manipulation can be baroque. We're using the arrow library to smooth that over: http://crsmithdev.com/arrow/
Upvotes: 1