Django
の管理サイトを構築するときに「 search_fields
」を使用してテキストボックスで検索条件を入力できるようにしているのですが、これだと一見するとどのフィールドで絞り込みを行っているのかが分からないので、今回は複数のテキストボックスの検索条件入力欄を作成し、どのフィールドで検索しようとしているのかを分かりやすくしてみようと思います。
前提条件
- Python : 3.6.2
- Django : 3.0.5
こちらのソースをベースに実装していきたいと思います。
search_fields を利用する方法
Django
の管理サイトでは「 search_fields
」を設定することでテキストボックスで検索できるようにすることができます。
@admin.register(User)
class UserAdmin(ExportMixin, admin.ModelAdmin):
...
search_fields = ['name', 'email']
...
検索条件を入力するテキストボックスが表示されるようになります。
ただ、これだとぱっと見て検索対象のフィールドがどれなのかが分かりません。
検索条件入力用のテキストボックスを複数作成する
まず、検索条件入力用のテキストボックスのベースとなる InputFilter
クラスを作成します。このクラスがテキストボックスの部品のベースとなります。
class InputFilter(admin.SimpleListFilter):
template = 'admin/input_filter.html'
def lookups(self, request, model_admin):
# Dummy, required to show the filter.
return ((),)
def choices(self, changelist):
# Grab only the "all" option.
all_choice = next(super().choices(changelist))
all_choice['query_parts'] = (
(k, v)
for k, v in changelist.get_filters_params().items()
if k != self.parameter_name
)
yield all_choice
次にテンプレートファイルを作成します。上記のクラスで template
に設定している path
にファイル( input_filter.html
)を追加します。
追加したファイルに下記のように実装します。
{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
<ul>
<li>
<form method="GET" action="">
{% for k, v in all_choice.query_parts %}
<input type="hidden" name="{{ k }}" value="{{ v }}" />
{% endfor %}
<input
type="text"
value="{{ spec.value|default_if_none:'' }}"
name="{{ spec.parameter_name }}"/>
</form>
</li>
</ul>
これで検索条件のテキストボックスのベースの部品の実装が完了しました。
それでは、それぞれのフィールドに対応したテキストボックスのフィルタを実装していきます。
# last_name
class NameFilter(InputFilter):
parameter_name = 'last_name'
title = '苗字'
def queryset(self, request, queryset):
if self.value() is not None:
last_name = self.value()
if last_name is None:
return
return queryset.filter(last_name__icontains=last_name)
# email
class EmailFilter(InputFilter):
parameter_name = 'email'
title = 'メールアドレス'
def queryset(self, request, queryset):
if self.value() is not None:
email = self.value()
if email is None:
return
return queryset.filter(email__icontains=email)
最後に UserAdmin
クラスの list_filter
に上記のクラスを設定します。
@admin.register(User)
class UserAdmin(ExportMixin, admin.ModelAdmin):
...
list_filter = [IsActiveListFilter, NameFilter, EmailFilter]
...
ここまで実装できたら実際に一覧画面を確認してみます。
苗字とメールアドレスの検索条件入力用のテキストボックスが一覧の右側にあるフィルタのところに追加されました!!
最後に
システムの中身を理解している人だけが管理サイトを使用する場合は、検索ボックスは一つでも問題ないかもしれませんが、そうでない場合は、検索条件入力用のテキストボックスはフィールドごとに分かれている方が検索もしやすくなると思います。
コメント