Djangoのテンプレート言語では、forループを使って現在の要素だけでなく、その1つ前の要素にもアクセスすることができます。これを実現する一つの方法は、forloop.counter
を使って現在のループのインデックスを取得し、それを使ってリストから1つ前の要素を取得することです。
以下は、この方法を使用した基本的な例です。
1.一つ前の要素を表示する
views.py
from django.views.generic import ListView
class MyListView(ListView):
template_name = 'index.html'
context_object_name = 'my_list'
def get_queryset(self):
return ['a', 'b', 'c', 'd']
次に、urls.py
ファイルでこのビューをURLにマッピングします。
urls.py
from django.urls import path
from . import views
app_name = 'ffreportapp'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
次に、テンプレートでこのリストをループ処理します。ここでforloop.counter0
を使って、現在のインデックスから1を引いて、1つ前の要素にアクセスします。
index.html
{% load custom_filters %}
{% for item in my_list %}
{% if forloop.counter > 1 %}
前の要素: {{ my_list|get_item:forloop.counter0|add:"-1" }}
<br>
{% endif %}
現在の要素: {{ item }}
{% endfor %}
の例では、カスタムテンプレートフィルタget_item
を使ってリストの要素にアクセスしています。Djangoにはデフォルトでリストインデックスに直接アクセスするフィルタはありませんので、以下のようなカスタムフィルタを作成する必要があります。
custom_filters.py
from django import template
register = template.Library()
@register.filter
def get_item(l, i):
try:
return l[i]
except:
return None
custom_filters.pyは下記のようなフォルダを作成します。
custom_filters.pyの配置は「templatetags」を新たに作成し、空の「__init__.py」ファイルを作成と「custom_filters.py」を入れます。
htmlの頭に入れているコード「{% load custom_filters %}」ファイル名「custom_filters」をロードするようにしています。
カスタムフィルターはserver起動状態だと反映されませんので一旦終了させてから再度「python manage.py runserver」を実行してください。
実行結果
以上でDjangoでhtmlテンプレートのfor文で1個前のデータを取得を終わります。
■.ダウンロードサービスのご案内
本記事で使用しているサンプルコードです。
注意:本記事の内容に関して運用した結果の影響については責任を負いかねます。あらかじめご了承ください。