はじめに
Djangoで作成したブログに投稿してから"1時間前"などの相対時刻表記を実装する方法を解説します。
もし、誤っていたり修正した方が良い箇所があればコメント欄にて指摘して頂けると嬉しいです。
環境
python 3.9
django 3.1.6
手順
1. 相対時刻表記で表示する
日付を呼び出す変数にtimesince
フィルターを付けます。
<p > {{ blog.posted_date|timesince }}前</p>
2. 時間単位を1つにする
1の手順を終えた時点で下記のように最大2つの時間単位がカンマ区切りで表示されます。
1 分
1 日, 2 時間
1 週間, 2 日
1 ヶ月, 2 週間
1 年, 2 ヶ月
これをカスタムテンプレートタグ・フィルターを使い1つの時間単位だけが表示されるようにします。
これにはカスタムテンプレートタグ・フィルターを定義する必要があります。
Q. カスタムテンプレートタグ・フィルターとは?
A. djangoには様々な組み込みタグ・フィルターが用意されていますが、自分で定義することも出来ます。これをカスタムテンプレートタグ・フィルターと呼びます。
導入方法やファイル名はDjango公式ドキュメントを
フィルターの構文はstackoverflowを参考にさせて頂きました。
アプリフォルダ内にtemplatetags
フォルダを作成し、
中に__init__.py
という空のファイルと[アプリ名]_extras.py
を作成します。
構成は下図の通りです。
myproject/blog/
├── __init__.py
├── models.py
├── templatetags
│ ├── __init__.py
│ └── blog_extras.py
└── views.py
タグ・フィルターを作成し、
from django import template
from django.template.defaultfilters import stringfilter # 文字列を想定したフィルター
register = template.Library()
@register.filter
@stringfilter
def upto(value, delimiter=None):
return value.split(delimiter)[0] # カンマの前までの部分を返す
upto.is_safe = True # カンマを含むため、自動エスケープを外す必要があります
index.html
で{% load blog_extras %}
で作成したフィルターを読み込み、
日付を呼び出す変数に作成したupto:','
フィルターを付けてください。
{% load blog_extras %}
<p > {{ blog.posted_date|timesince|upto:',' }}前</p>
記事中では紹介しておりませんが、下記のサイトも参考にさせて頂きました。
https://medium.com/@kjmczk/django-timesince-176780a9005
https://djangobrothers.com/blogs/custom_template_tags_filters/