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

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

以下の記事の続きです。

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

条件

  • Django 2.1.3
  • Python 3.7.0
  • PyCharm Professional

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

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

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

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

  • デフォルトのユーザーモデルが、作成するプロジェクトが必要とする認証のモデルと合致するとは限らない。
  • プロジェクト途中からのカスタムユーザーモデルへの変更は困難である。
    • 自動ではなく手動で各種変更を行う必要がある。

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

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

  • AbstractUser
    • 基本的にはすでに使用されている「User」クラス。
    • コーディング量が少なく容易。
    • 属性を追加するだけ等の場合に使用する。
  • AbstractBaseUser
    • ユーザー名やその他フィールドを記述する必要がある。
    • コーディング量は多くなるがAbstractUserより柔軟性がある。

ここでは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

コメントを残す

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