(最終更新月:2021年7月)
日報アプリを作成しています
django-filterを使って、「年月別のフィルターを作りたい!」と思ったのですが特に方法が書いてあるページが見当たらない!
そもそも備え付けのフィルターで事足りるからだと思いますが、django-filterで他の機能も追加していく予定なので、このままdjango-filterで作ることにしました
今回の記事では、
という方法の解説となります
そもそも「django-filterを使ったことがない!」という方はdjango-filterの導入から各ファイルの設定までを解説したこちらの記事をご覧ください
【コード全体】filter.py
下記にて、各パートについて解説をしますが、最終的にはこんな感じになりました
import django_filters
from .models import NippoModel
from distutils.util import strtobool
qs = NippoModel.objects.all()
choice_option = [(obj.timestamp.year, obj.timestamp.month) for obj in qs]
choice_option = list(set(choice_option))
DATE_OPTIONS = [((year, month), f"{year}年{month}月") for year, month in choice_option]
DATE_OPTIONS.insert(0, (None, "---"))
class NippoModelFilter(django_filters.FilterSet):
public = django_filters.BooleanFilter(label="公開")
timestamp = django_filters.TypedChoiceFilter(choices=DATE_OPTIONS,method="timestamp_checker", label="公開月")
class Meta:
model = NippoModel
fields = ["public", "timestamp"]
def timestamp_checker(self, queryset, name, value):
if value is not None:
year, month = eval(value)
return queryset.filter(timestamp__year=year).filter(timestamp__month=month)
else:
return queryset
「よくわからない!」という方に向けて、次章よりパートごとの解説をしていきます
※publicについて、BooleanFilterを設定してますが、当記事で解説は省きます
詳しくは、公式ドキュメントなどご覧ください
モデルのフィールドについては、こちらで解説しています↓(publicは後から追加しました)
保存しているデータの年月を抽出、リスト化
qs = NippoModel.objects.all()
choice_option = [(obj.timestamp.year, obj.timestamp.month) for obj in qs]
choice_option = list(set(choice_option))
※「内包表記って何?」という方はこちら↓の記事をご覧ください!
今回のリストはこんなものになっています
choice_option = [(2021, 5), (2021, 6), ...]
フィルターへ渡す用のリストを作成
前章で作ったリストを、フィルターのchoces引数へ渡すために変更します
通常のリストを
[(受け取る値, テンプレートで表示される文字列), ...」
となるよう変更します
DATE_OPTIONS = [((year, month), f"{year}年{month}月") for year, month in choice_option]
DATE_OPTIONS.insert(0, (None, "---"))
filterクラスの作成
ベースとなるクラスの作成方法についてはこちらの記事をご覧ください↓
対象の部分を抜粋すると、
class NippoModelFilter(django_filters.FilterSet):
...
timestamp = django_filters.TypedChoiceFilter(choices=DATE_OPTIONS,method="timestamp_checker", label="公開月")
...
def timestamp_checker(self, queryset, name, value):
if value is not None:
year, month = eval(value)
return queryset.filter(timestamp__year=year).filter(timestamp__month=month)
else:
return queryset
まとめ
django-filterで年月別リスト表示をするために、
- 保存したデータの年月を取り出す
- 取り出した年月をリスト化し、フィルターに渡す
- メソッドを使い受け取った値で適切なクエリセットを返す
方法を解説しました
前章までのコードをコピペなどを使い、皆様のWebアプリ制作の一助になれたら幸いです
日報アプリを一から開発し、ウェブに公開するまではこちらにまとめています
また、公開したウェブアプリはこちら(https://nippo.itc-app.site)でご覧いただけます(公開後もアップデート中)
その他、各分野別に
を記載したページも用意しています
ご自身の目的に合わせて、お好きな箇所からご覧ください
