I think it's a common case that you want to put the Badge New! On a new article on the article list page of a site like a blog. One way to do this in Django is to add a new or not bool to the Context, but I don't think it's a good idea to do this in a ListView. This time, I will show you how to make your own template filter and judge whether it is a new article in the template.
Create a templatetags /
directory in <project folder> / <application folder> /
.
This application must be written in INSTALLED_APP in settings.py
.
Create a file with <arbitrary name> .py
in the created directory.
The {% load <arbitrary name>%}
in the template, so be careful with the naming.
This time, we'll take a value of type datetime and create a filter to determine if it's the last week. Since this filter is used to branch the if statement, the return value should be bool.
python:.../templatetags/sample_filter.py
"""
Template tag to determine if date is the last week
"""
import datetime
from django import template
from django.utils import timezone
register = template.Library()
@register.filter(expects_localtime=True)
def is_new(dt: datetime.datetime):
#Base date for new or not
criteria_date = timezone.now() - datetime.timedelta(weeks=1)
return dt >= criteria_date
From the official Doc
If you write a custom filter that operates on datetime objects, you'll usually register it with the expects_localtime flag set to True:
When you create a custom filter that works with a datetime object, you typically register it with the expects_localtime flag set to True.
When this flag is set, if the first argument to your filter is a time zone aware datetime, Django will convert it to the current time zone before passing it to your filter when appropriate, according to rules for time zones conversions in templates.
When this flag is set, if the first argument to the filter is a timezone-aware date and time, Django will follow the template's timezone conversion rules and the current timezone before passing it to the filter at the appropriate time. Convert to.
In other words, it is an argument required when performing calculations considering the time zone. The datetime passed to the filter function will be the value considering the time zone.
If you do it as @ register.filter (name ='foo')
, you can use the filter with the name foo in the template.
If you do not pass the name argument, the function name will be the name of the filter.
Since we haven't passed the name argument this time, we'll use the filter with the name ʻis_new`.
template It is used as follows in the template. The following is an example of displaying a list of notifications and attaching a new! Badge within a week. I'm using bootstrap. It's a lot cleaner than passing a bool that determines if it's new to the context.
template
{% load sample_filter %}
...
{% for news in news_list %}
<a href="{% url 'news:detail' news.pk %}" class="list-group-item list-group-item-action">
<span>{{ news.publish_time |date:"Y year m month d day H:i" }}</span>
<span class="badge badge-primary">{{ news.category }}</span>
{{ news.subject }}
<!--Judge whether to attach a new badge-->
{% if news.publish_time|is_new %}
<span class="badge badge-info badge-new">new!</span>
{% endif %}
</a>
{% empty %}
<p>There is no notification.</p>
{% endfor %}
...
Like the date filter used in the code above, the filter can also take arguments. This is a quote from the official Doc,
def cut(value, arg):
"""Removes all values of arg from the given string"""
return value.replace(arg, '')
{{ somevariable|cut:"0" }}
Can be used as. When get_context_data etc. becomes bloated, it may be one way to use a template filter.
Unique template tags and filters|Django documentation| Django https://docs.djangoproject.com/ja/2.2/howto/custom-template-tags/
Recommended Posts