BLOGサブスレッドの日常

2016.04.27

Djangoの管理サイトでカスタムユーザーモデルを扱う

torikai

水曜日担当の秋山です。よろしくお願いします。

今回は、Djangoネタです。

ちょっと躓いたところの備忘録的なものなので、細かいところの説明は省略してます(・・ゞ

Djangoの管理サイト

Djangoの大きな特徴と言っても良いぐらいの機能として、管理サイトが組み込まれています。

高性能なCRUD機能が用意されていて、セットアップの為のコーディングもお手軽。

なので、開発の早い段階からデータベースに格納されているデータの一覧、検索、登録、削除、編集…といった事が可能です。

あくまで開発用として割り切って使っている機能ですが、ユーザー認証に使っているモデルをこの管理サイトで扱う場合、ちょっと書き方が変わるんですね。

カスタムユーザーモデルの設定

例えば、こんなモデルの設定をしていたとして…

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin


class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, username, password, is_superuser, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        user = self.model(username=username, is_superuser=is_superuser, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, password, **extra_fields):
        return self._create_user(username, password, True, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField('ユーザー名', max_length=30, unique=True)
    screenname = models.CharField('ユーザー名(表示用)', max_length=255)
    email = models.CharField('メールアドレス', max_length=255)
    is_active = models.BooleanField('有効フラグ', default=True)
    is_staff = models.BooleanField('スタッフ', default=True)
    created_date = models.DateTimeField('登録日時', auto_now_add=True)
    modified_date = models.DateTimeField('更新日時', auto_now=True)

    objects = UserManager()
    USERNAME_FIELD = 'username'

    class Meta:
        verbose_name = 'ユーザー'
        verbose_name_plural = verbose_name

    def get_full_name(self):
        return self.__str__()

    get_short_name = get_full_name

あとは、管理サイトへログインするためのユーザーを作っておきます。

いわゆる「普通」の管理サイトの設定

管理サイトの設定は、Djangoのアプリケーション配下にあるadmin.pyに書いていきます。

from django.contrib import admin
from . import models
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm

class UserAdmin(UserAdmin):
    list_display = ('username', )
    search_fields = ('username', )

こんな感じで。

ここまで書いたら、後は特に何もしなくても、/admin からアクセス出来ます。

例えばローカル開発環境で8000番ポートでサーバを起動している時とかは、http://localhost:8000/adminとかですね。

実際にアクセスしてみるとこんな画面になってます。

おおー、お手軽。

ログインしていくと、こんな感じで。先ほど追加したユーザーモデルが "MANAGER" に入ってます。

早速ユーザー追加をしてみます。

入力画面も、それっぽい感じになってますね。

で、保存ボタンを押すと、ユーザーが作成…

(´・ω・`)

…ブラウザバックで先ほどのユーザー一覧の画面に戻ったのがこちら。

ちゃっかり作成されている割に、編集しようとすると先ほどのエラーが出ます… つらい…

カスタムユーザーモデルの為の管理サイトの設定

という訳で、ちょっと変わった書き方が必要になってきます。

class UserChangeForm(UserChangeForm):
    class Meta(UserChangeForm.Meta):
        model = models.User


class UserAdmin(UserAdmin):
    form = UserChangeForm
    fieldsets = (
        (None, {'fields': ('username', 'password', 'screenname', )}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'password1', 'password2'),
        }),
    )
    list_display = ('username', 'screenname', )
    list_filter = ('username', )
    search_fields = ('username', )
    ordering = ('username', )
    filter_horizontal = ()


admin.site.register(models.User, UserAdmin)

先ほど書いたUserAdminクラスは削除してしまって、こんな感じにしまして…

管理サイトを開いて、ユーザー追加してみます。

やったー。

2つ目の入力画面で、ここfieldsetsに指定しているscreennameが表示されてますね。

このまま登録をすると、

やったー。

無事、管理サイトからカスタムユーザーの情報を登録できました!

もしかしたら…

こんな回りくどく書かなくても、さくっと書けるのかもしれないですけども…(^^;

今後の開発を通して、もっと良い方法に気づいたら、またブログに書くかもしれません。

それではー。

この記事を書いた人

torikai