Django Logo

[Django]管理者サイトの一覧のフィルタを追加する

Django の管理サイトの一覧画面でフィルタを追加する方法を説明します。

こんなフィルタが追加されます。
Django Fillter 1

ソースは以下のサイトにありますので、参考までにどうぞ!

User モデル

今回使用する User モデルは下記のモデルを使用します。

class User(AbstractBaseUser, PermissionsMixin):
    """
    ユーザモデル
    """
    class Meta:
        verbose_name = 'ユーザ'
        verbose_name_plural = 'ユーザ'
        app_label = 'accounts'

    username = models.CharField(verbose_name='ユーザID',
                                unique=True,
                                max_length=30)
    password = models.CharField(verbose_name='パスワード',
                                max_length=128,
                                blank=True)
    last_name = models.CharField(verbose_name='苗字',
                                 max_length=30,
                                 default=None)
    first_name = models.CharField(verbose_name='名前',
                                  max_length=30,
                                  default=None)
    zip = models.CharField(verbose_name='郵便番号',
                           max_length=8,
                           default=None,
                           null=True,
                           blank=True)
    prefecture = models.CharField(verbose_name='都道府県',
                                  max_length=50,
                                  default=None,
                                  null=True,
                                  blank=True)
    city = models.CharField(verbose_name='市区町村',
                            max_length=100,
                            default=None,
                            null=True,
                            blank=True)
    address = models.CharField(verbose_name='番地',
                               max_length=100,
                               default=None,
                               null=True,
                               blank=True)
    email = models.EmailField(verbose_name='メールアドレス',
                              null=True,
                              default=None,
                              blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(verbose_name='有効フラグ',
                                    default=True)
    is_staff = models.BooleanField(verbose_name='管理サイトアクセス権限',
                                   default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email', 'last_name', 'first_name']
    objects = UserManager()

    def __str__(self):
        if self.last_name and self.first_name:
            return self.last_name + ' ' + self.first_name
        else:
            return self.last_name

    def get_short_name(self):
        return self.last_name

    def get_full_name(self):
        return self.last_name + ' ' + self.first_name

admin.py 実装

admin.py を以下のように実装します。

from django.contrib import admin
from django.contrib.auth.hashers import make_password
from django.utils.safestring import mark_safe

from .models import User

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        """
        モデルの保存
        :param request:
        :param obj:
        :param form:
        :param change:
        :return:
        """
        if change:
            user = User.objects.get(pk=obj.pk)
            if not user.password == obj.password:
                obj.password = make_password(obj.password)
        else:
            obj.password = make_password(obj.password)
        obj.save()

    list_display = ['username', 'name', 'email', 'merge_address']
    ordering = ['username']
    list_filter = ['is_active']

    def name(self, obj):
        return obj.last_name + ' ' + obj.first_name

    name.short_description = '氏名'

    def merge_address(self, obj):
        address = ''
        if obj.zip:
            address += obj.zip + '<br>'
        if obj.prefecture:
            address += obj.prefecture + '<br>'
        if obj.city:
            address += obj.city + '<br>'
        if obj.address:
            address += obj.address

        return mark_safe(address)

    merge_address.short_description = '住所'

既存のソースに、

    list_filter = ['is_active']

を追加して、「 is_active 」のフィルタを追加します。

これでユーザ一覧画面( http://localhost:8000/admin/accounts/user/ )を開くと、
Django Fillter 2

こんな感じでフィルタが追加されます。
これでフィルタの追加はできたんですが、「はい」「いいえ」とかだと若干分かりにくいので、「はい」は「有効」、「いいえ」は「無効」と文言を変更してみたいと思います。

フィルタの文言を変更するクラスの実装

IsActiveListFilter クラスを実装します。

class IsActiveListFilter(admin.SimpleListFilter):
    title = '有効フラグ'
    parameter_name = 'is_active'

    def lookups(self, request, model_admin):
        return (
            ('True', '有効'),
            ('False', '無効')
        )

    def queryset(self, request, queryset):
        if self.value() == 'True':
            return queryset.filter(is_active=True)
        elif self.value() == 'False':
            return queryset.filter(is_active=False)
        else:
            return queryset.all()

実装したクラスを使用するために、「 list_filter 」で「 IsActiveListFilter 」を呼び出します。

    list_filter = [IsActiveListFilter]

動作確認

では、実際に文言が変更されたか確認してみます。

ユーザ一覧画面( http://localhost:8000/admin/accounts/user/ )にアクセスすると、
Django Fillter 3

フィルタの文言が変更されているのが確認できました!!

最後に

管理サイトを一般ユーザに利用してもらう場合、あまりシステム寄りの文言だと理解してもらえないこともあると思いますので、そういう時は今回のように文言を編集することで、ユーザに分かりやすいサイト作りができるようになると思います。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です