Django 標準の User モデルは username・email・password などの基本フィールドを備えていますが、実際のプロジェクトでは「電話番号を必須にしたい」「メールアドレスでログインしたい」といった要件がほぼ確実に出てきます。Django ではプロジェクト開始時にカスタムユーザーモデルを作っておくことが公式に推奨されています。
なぜカスタマイズが必要か
標準の User モデルはログイン ID が username 固定で、追加フィールドを持ちません。後からユーザーモデルを差し替えるのは既存データのマイグレーションが非常に複雑になるため、プロジェクトの初期段階で対応しておくのが鉄則です。
username でログイン。フィールドの追加や変更ができない
ログイン ID やフィールドを自由に変更できる。プロジェクト開始時に作るのが推奨
AbstractUser を使った拡張
最もシンプルなカスタマイズ方法は AbstractUser を継承することです。標準の User モデルが持つすべてのフィールドと機能を引き継ぎながら、独自のフィールドを追加できます。
# accounts/models.py from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): phone = models.CharField(max_length=20, blank=True, verbose_name='電話番号') bio = models.TextField(blank=True, verbose_name='自己紹介') date_of_birth = models.DateField(null=True, blank=True, verbose_name='生年月日')
AbstractUser を継承しているため、username・email・password・first_name・last_name・is_active・is_staff などの標準フィールドはそのまま使えます。ここに phone・bio・date_of_birth を追加しただけです。
AUTH_USER_MODEL の設定
カスタムユーザーモデルを Django に認識させるには、settings.py に AUTH_USER_MODEL を設定します。
# settings.py AUTH_USER_MODEL = 'accounts.User'
この設定は migrate を実行する前に行う必要があります。すでにデフォルトの User モデルでマイグレーションを実行した後に変更すると、テーブルの不整合が発生します。
accounts アプリを作成する
AbstractUser を継承したモデルを定義する
AUTH_USER_MODEL を settings.py に設定する
makemigrations → migrate を実行する
他のモデルからの参照
カスタムユーザーモデルを外部キーで参照するときは、settings.AUTH_USER_MODEL を使います。from django.contrib.auth.models import User を直接インポートしてはいけません。
from django.conf import settings from django.db import models class Article(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='articles' )
settings.AUTH_USER_MODEL は文字列('accounts.User')を返すため、モデルの定義順序に依存せず安全に参照できます。ビューやフォームでユーザーモデルを取得する場合は get_user_model() を使います。
from django.contrib.auth import get_user_model User = get_user_model() users = User.objects.all()
モデル定義の ForeignKey 等で使う。文字列で参照するため循環インポートを回避できる
ビューやフォームで使う。実際のモデルクラスを返す
メールアドレスでログインする
username の代わりにメールアドレスでログインさせたい場合は、USERNAME_FIELD を変更します。
from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): email = models.EmailField(unique=True, verbose_name='メールアドレス') phone = models.CharField(max_length=20, blank=True, verbose_name='電話番号') USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username']
USERNAME_FIELD を 'email' に変更すると、authenticate 関数や管理画面のログインがメールアドレスベースに切り替わります。email フィールドには unique=True が必須です。ログイン ID として使うフィールドに重複があってはならないためです。
REQUIRED_FIELDS は createsuperuser コマンドで入力を求められるフィールドのリストです。USERNAME_FIELD に指定したフィールドと password は自動で含まれるため、ここには含めません。
管理画面への対応
カスタムユーザーモデルを管理画面で使うには、UserAdmin を継承してカスタマイズします。
# accounts/admin.py from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import User class CustomUserAdmin(UserAdmin): fieldsets = UserAdmin.fieldsets + ( ('追加情報', {'fields': ('phone', 'bio', 'date_of_birth')}), ) add_fieldsets = UserAdmin.add_fieldsets + ( ('追加情報', {'fields': ('phone', 'bio', 'date_of_birth')}), ) admin.site.register(User, CustomUserAdmin)
UserAdmin.fieldsets に追加フィールドをタプルで連結しています。add_fieldsets はユーザー新規作成画面のフィールド設定で、こちらにも追加フィールドを含めておくと管理画面からの登録時に入力できるようになります。
AbstractBaseUser という選択肢
AbstractUser はフィールド構成をあまり変えずに拡張したい場合に最適ですが、username フィールドを完全に削除したいなど、根本的にモデル構造を変えたい場合は AbstractBaseUser を使います。
標準の User モデルをそのまま継承。フィールドの追加が中心のカスタマイズに向く。認証バックエンドや権限の仕組みがすべて引き継がれるため、設定が最小限で済む。
パスワード管理と認証の基盤だけを提供。フィールド構成を完全に自由に設計できるが、権限の仕組み(PermissionsMixin)を自分で組み込む必要がある。
ほとんどのプロジェクトでは AbstractUser で十分です。AbstractBaseUser が必要になるのは、username フィールド自体が不要、あるいはフィールド構成を根本から設計し直したいようなケースに限られます。
カスタムユーザーモデルはプロジェクト開始時にしか安全に導入できない設定です。たとえ最初は標準の User モデルで十分に見えても、AbstractUser を継承した空のモデルだけは作っておく——これが Django 開発におけるベストプラクティスになっています。