[Django 2.2] Add a New badge to new posts with a date using a template filter

Overview

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.

environment

File creation

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 here is {% load <arbitrary name>%} in the template, so be careful with the naming.

Create a filter

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

About ʻexpects_localtime = True`

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.

naming

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 %}
    ...

other

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.

reference

Unique template tags and filters|Django documentation| Django https://docs.djangoproject.com/ja/2.2/howto/custom-template-tags/

Recommended Posts

[Django 2.2] Add a New badge to new posts with a date using a template filter
Make a filter with a django template
How to do arithmetic with Django template
How to add a package with PyCharm
[Django] I made a field to enter the date with 4 digit numbers
Try using django-import-export to add csv data to django
How to develop a cart app with Django
If you want to display values using choices in a template in a Django model
Try to create a Todo management site using WebSocket with Django (Swamp Dragon)
Create a shogi game record management application using Django 5 ~ Pass DB data to Template ~
I tried to create a table only with Django
(Python) Try to develop a web application using Django
When you want to filter with Django REST framework
Transit to the update screen with the Django a tag
[Morphological analysis] How to add a new dictionary to Mecab
Model.objects.extra to consider before using raw SQL with Django
[Django] A pattern to add related records after creating a record
I made a package to filter time series with python
I want to make a blog editor with django admin
How to resolve CSRF Protection when using AngularJS with Django
How to add new data (lines and plots) using matplotlib
How to generate a query using the IN operator in Django
The usual way to add a Kernel with Jupyter Notebook
Add a dictionary to MeCab
Create a homepage with django
Using a printer with Debian 10
Create a shogi game record management app using Django 6 ~ Template division ~
Rails users try to create a simple blog engine with Django
Try to edit a new image using the trained StyleGAN2 model
I tried to make a regular expression of "date" using Python
Here's a brief summary of how to get started with Django
Output search results of posts to a file using Mattermost API
I tried to make a todo application using bottle with python
Create a REST API to operate dynamodb with the Django REST Framework
[Tips] How to do template extends when creating HTML with django
A super introduction to Django by Python beginners! Part 3 I tried using the template file inheritance function
A super introduction to Django by Python beginners! Part 2 I tried using the convenient functions of the template