サイトアイコン 知的好奇心

Djangoでカスタムユーザーモデルを実装する方法

Djangoでカスタムユーザーモデルを実装する方法をご紹介します。

以下の記事の続きです。

Djangoのログイン処理を実装する方法④~サインアップ~

条件

なぜカスタムユーザーモデルか?

Djangoの公式ドキュメントでは、プロジェクト開始時にカスタムユーザーモデルを作成することを強く推奨しています。

https://docs.djangoproject.com/ja/2.1/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project

理由は主に以下の2つです。

カスタムユーザーモデル作成方法

カスタムユーザーモデルの作成方法は2通りあります。

ここではAbstractUserを使用することとします。

参考
https://stackoverflow.com/questions/21514354/difference-between-abstractuser-and-abstractbaseuser-in-django

公式ドキュメント
https://docs.djangoproject.com/ja/2.1/topics/auth/customizing/#extending-the-existing-user-model

models.py

accounts/models.pyに以下のようにCustomUserクラスを追加します。

# accounts/models.py
from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):

    def __str__(self):
        return self.email

settings.py

プロジェクトレベルのsettings.pyに以下を追加します。

#sample/settings.py

# カスタムユーザモデル
AUTH_USER_MODEL = 'accounts.CustomUser'

forms.py

accounts/forms.pyを作成します。
CustomUserCreationFormとCustomUserChangeFormの2つのクラスを作成します。

# accounts/forms.py

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser


class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('username', 'email')


class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

admin.py

admin.pyを修正します。

# accounts/admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser


class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ['email', 'username',]


admin.site.register(CustomUser, CustomUserAdmin)

DBへの反映

マイグレーションファイル作成

Ctrl + Alt + Rでmanage.pyコンソールを開きます。
manage.pyコンソールで以下のコマンドを実行します。

makemigrations accounts

⇒accounts/migrationsの下に0001_initial.pyが作成されます。

マイグレーションファイルをデータベースに適用

manage.pyコンソールで以下のコマンドを実行します。

migrate

以下のようなエラーが出力されました。

django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency accounts.0001_initial on database 'default'.

db.sqlite3ファイルを削除して「migrate」を再実行します。
コマンドが正常終了しdb.sqlite3ファイルが再作成されました。

管理者ユーザー作成

manage.pyコンソールで以下のコマンドを実行します。

createsuperuser

ユーザー名、メールアドレス、パスワードを入力してユーザーを作成します。
ここではユーザー名「admin」で作成しました。

動作確認

作成したユーザーでログインします。

ログアウトしてサインアップ画面を開きます。

現段階では「ユーザー名」と「パスワード」のみが入力項目となっています。

views.pyの修正

accounts/views.pyを以下のように修正します。
(UserCreationFormをCustomUserCreationFormに変更します)

# accounts/views.py

from django.urls import reverse_lazy
from django.views import generic
from .forms import CustomUserCreationForm # 追加


class SignUp(generic.CreateView):
    form_class = CustomUserCreationForm #ここを変更
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

動作確認

再度、サインアップ画面を開きます。
入力項目に「パスワード」が追加されていることがわかります。

メールアドレスを必須項目にする

forms.pyを以下のように修正します。
フォームにおける入力項目定義はデフォルトで必須(required=True)になっているため、メールアドレスが必須項目となります。

# accounts/forms.py

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
from django import forms


class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('username', 'email')

    email = forms.EmailField() # 追加


class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

    email = forms.EmailField() # 追加

上記の設定で、サインアップ画面と管理画面でメールアドレスが必須項目となります。

参考

本記事は主に以下のサイトを参考にさせていただきました。

Django: How to Extend The User Model
https://wsvincent.com/django-custom-user-model-tutorial/
Django

モバイルバージョンを終了