Djangoのユーザーモデルとアドミンパネルをカスタムしよう

準備するもの

・Python3

・Djangoの基礎知識

イントロ

DjangoでデフォルトでついてくるユーザーモデルはEmailと名前くらいのシンプルなものですね。

今日は、Djangoについてくるユーザーモデルにこれから使う、従業員管理に合わせてモデルを追加していきます。

今日紹介する内容はこのリンクからも公式ドキュメントで確認できます。

https://docs.djangoproject.com/en/4.0/topics/auth/customizing/

解決できる課題

Djangoのユーザーモデルに従業員の電話番号などの情報を追加できるようになる。

Djangoのアドミンパネルで検索機能を付ける。

Djangoのアドミンパネルに表示するデータを増やす。

下準備

今回は、従業員のチケット管理アプリのバックエンドを想定したサンプルコードを紹介します。

下から完成したサンプルコードをダウンロードしてください。

https://github.com/TraitOtaku/djangoAPI/tree/9_CustomUserModel

ではいつものようにgitのコマンドを使ってリポジトリをクローンしましょう。

Gitの使い方はこちらの動画で説明しています。

git clone https://github.com/TraitOtaku/djangoAPI.git

cd DjangoAPI

git branch -a

git checkout 9_CustomuserModel

バーチャル環境を設定しましょう。

pip install virtualenv

virtualenv env

env\Scripts\activate

pip install -r requirements.txt

Djangoを設定していきます。

python manage.py makemigrations

python manage.py migrate

python manage.py createsuperuser

python manage.py runserver

カスタムUserモデルを作ろう

まずは、デフォルトのDjangoのユーザーモデルをインポートして上書きしていく作業になります。

下記のモジュールをインポートしています。

from django.utils.translation import gettext_lazy as _

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

ユーザーモデル

では、下記のモデルを見てみましょう。

AbstractBseUserからDjangoのUserモデルを引っ張ってきています。

class Member(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(_('email address'), unique=True)

    user_name = models.CharField(max_length=150, unique=True)

    first_name = models.CharField(max_length=150, blank=True)

    last_name = models.CharField(max_length=150, blank=True)

    phone = models.CharField(max_length=150, blank=True)

    about = models.TextField(_(

        'about'), max_length=500, blank=True)

    is_staff = models.BooleanField(default=False)

    is_active = models.BooleanField(default=False)



    objects = CustomAccountManager()



    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = ['user_name', 'first_name']



    def __str__(self):

        return self.user_name

USERNAME_FIELD = ’email’ でログインする際のユーザーネームの代わりにEmailとパスワードでログインできるようになります。

REQUIRED_FIELDSはユーザーを作成する際に必須な項目の事です。

objects = CustomAccountManager()でアドミンの権限のあるユーザーの設定を上書きします。

BaseUserManager

今度は、アドミン権限のあるユーザーの設定を上書きしていきます。

class CustomAccountManager(BaseUserManager):



    def create_superuser(self, email, user_name, first_name, password, **other_fields):



        other_fields.setdefault('is_staff', True)

        other_fields.setdefault('is_superuser', True)

        other_fields.setdefault('is_active', True)



        if other_fields.get('is_staff') is not True:

            raise ValueError(

                'Superuser must be assigned to is_staff=True.')

        if other_fields.get('is_superuser') is not True:

            raise ValueError(

                'Superuser must be assigned to is_superuser=True.')



        return self.create_user(email, user_name, first_name, password, **other_fields)



    def create_user(self, email, user_name, first_name, password, **other_fields):



        if not email:

            raise ValueError(_('You must provide an email address'))



        email = self.normalize_email(email)

        user = self.model(email=email, user_name=user_name,

                          first_name=first_name, **other_fields)

        user.set_password(password)

        user.save()

        return user

Settings.pyの設定

このファイルのどこかに下記のラインを追加しましょう。

これでDjangoがMemberモデルを使ってユーザー認証をするように指示できます。

AUTH_USER_MODEL = 'members.Member'

Admin.pyの設定

ではアドミンパネルの表示をカスタマイズしていきます。

from django.contrib import admin

from .models import Member, Office

from django.contrib.auth.admin import UserAdmin



class UserAdminConfig(UserAdmin):

    model = Member

    search_fields = ('email', 'user_name', 'first_name',)

    list_filter = ('email', 'user_name', 'first_name', 'is_active', 'is_staff')

    ordering = ('email',)

    list_display = ('email', 'user_name', 'first_name',

                    'is_active', 'is_staff')

    fieldsets = (

        (None, {'fields': ('email', 'user_name',

         'first_name', 'last_name', 'phone', 'password')}),

        ('Permissions', {'fields': ('is_staff', 'is_active')}),

    )

    # formfield_overrides = {

    #     NewUser.about: {'widget': Textarea(attrs={'rows': 10, 'cols': 40})},

    # }

    add_fieldsets = (

        (None, {

            'classes': ('wide',),

            'fields': ('email', 'user_name', 'first_name', 'phone', 'password1', 'password2', 'is_active', 'is_staff')}

         ),

    )



admin.site.register(Office)

admin.site.register(Member, UserAdminConfig)

見たままの感じですがこれをもとにするとアドミンパネルももっと使いやすくなりますね。

ではおつかれさまです。