プログラミング

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

プログラミング
この記事は約9分で読めます。
スポンサーリンク

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

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

ソースは下記にありますので、参考までにどうぞ!

koichi-ezato/sample
Contribute to koichi-ezato/sample development by creating an account on GitHub.
スポンサーリンク

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/)を開くと、

こんな感じでフィルタが追加されます。

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

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

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/)にアクセスすると、

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

最後に

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

スポンサーリンク
スポンサーリンク
KoEをフォローする
CodeLab

コメント

タイトルとURLをコピーしました