#はじめに
業務とは別に個人的に何かサービスを作りたいなと思ったので色々勉強しているのですが、
その中でUserモデルをカスタマイズしたいなと思った時があったのでそれについて記載します。
Djnago歴は浅くまだまだ学習中の身ですので、何かありましたらご指摘お願いします!
なお、本記事はコチラを参考に作成しました。
##実装
既存のプロジェクトをいじっていく予定ですので、最初の設定などは飛ばしています。
また、今回はYouTuber向けのサービスのアカウント情報を登録する程で作ってみました。
例えば、first_nameやlast_nameを削除しchannel_nameを入れたりといった感じ。
手順としては下記の手順で進めていきます。
- usersアプリ作成
- AbstractBaseUserを継承したUserクラスを作成
- UserAdmin を継承したクラスを作成。
まずusers
アプリを作成します。
python manage.py startapp users
アプリを作成したらsettings.py
に追加する必要があるので追記します。
それと一緒にAUTH_USER_MODEL
も追記します。
'users.User'
のusersは先程作成したアプリ名です。
INSTALLED_APPS = [
'mainApp',
'users', #### 追加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
AUTH_USER_MODEL = 'users.User'
次に、users/models.py
にUserモデルを記載します。
とりあえずコードは下記の通りになります。
コードの説明は下に記述しております。
from django.contrib.auth import validators
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.core.mail import send_mail
from django.utils import timezone
import uuid as uuid_lib
class User(AbstractBaseUser, PermissionsMixin):
uuid = models.UUIDField(
default=uuid_lib.uuid4,
primary_key=True,
editable=False
)
username_validators = UnicodeUsernameValidator()
username = models.CharField(
"ユーザ名",
max_length=150,
unique=True,
help_text="※150文字以下の文字や数字、一部の記号で入力したください。",
validators = [username_validators],
error_messages={
"unique": "このユーザー名は既に使用されています。",
},
)
channel_name = models.CharField("チャンネル名", max_length=150, blank=True)
email = models.EmailField("Eメールアドレス", blank=True)
is_staff = models.BooleanField(
"ユーザステータス",
help_text="ユーザーがこの管理サイトにログインできるかどうかを指定します。",
default=False,
)
is_member = models.BooleanField(
"会員ステータス",
help_text="このユーザが契約しているかを区別します。",
default=False,
)
is_active = models.BooleanField(
"アクティブユーザ",
help_text="このユーザーをアクティブとして扱うかどうかを指定します。アカウントを削除する代わりに、これを選択解除してください。",
default=True,
)
date_joined = models.DateTimeField("登録日", default=timezone.now)
objects = UserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email',]
class Meta:
verbose_name = "user"
verbose_name_plural = "users"
def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email)
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
AbstractBaseUser
Userモデルのカスタマイズを行うために必要なクラス
PermissionsMixin
AbstractBaseUserはパーミッション関連の機能を持っていないので、
パーミッションの機能を利用したい場合は、PermissionsMixinを同時に継承しておく。
UserManager
UserManagerを使うということをDjangoに知らせています。
これにより、今後「create_user」、「create_superuser」のメソッドを呼ぶときに
UserManagerクラスの「create_user」、「create_superuser」のメソッドが呼ばれる。
UnicodeUsernameValidator
不正な文字列が含まれていないかチェックするためのクラスらしいです。
send_mail
簡単なメールに使うためのメソッド
primary_key
そのカラムが プライマリーキーになり、 id は生成されなくなります。
editable
編集ができなくなる
unique
被りNG
help_text
Formでこういう風に入力してほしいとヘルプ(ヒント)をつけたいときに記載
validators
先程定義したバリデーションを記載
verbose_name
管理画面のモデル名を指定
verbose_name_plural
複数形の場合の名称を指定
といった感じです。
次にadmin.pyを修正していきたいと思います。
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from .models import User
@admin.register(User)
class AdminUserAdmin(UserAdmin):
fieldsets = (
(None, {"fields": ("username", "password")}),
("Personal info", {"fields": ("channel_name", "email")}),
("Permissions", {"fields": ("is_active", "is_member", "is_staff", "is_superuser", "groups", "user_permissions")}),
("Important dates", {"fields": ("last_login", "date_joined")}),
)
list_display = ("username", "channel_name", "is_member", "last_login")
search_fields = ("username", "channel_name", "email")
filter_horizontal = ("groups", "user_permissions")
fieldsetsで管理画面に表示する内容を指定します。
タプル型で記載をしていきます。
第一引数のタプルですが、Noneを指定することにより下画像の
ユーザ名、パスワードの箇所の設定を行います。
つまり、(None, {"fields": ("username", "password")})
の箇所を
(None, {"fields": ("username", "password", "channel_name)})
とすれば、
管理画面では、ユーザ名、パスワード、チャンネル名が表示されます。
そしてその下に、Personal info
が表示されます。
Personal infoの内容もfieldsetsで指定可能です。
models.pyとadmin.pyの記述が完了したら、
makemigrations
とmigrate
、createsuperuser
を実行します。
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser
なお、マイグレーションなどが失敗する場合はmigrationsディレクトリを削除したり、
データベースごと削除してしまうと解決が早いっぽいです。
私はデータベースを削除しました・・・。
#さいごに
以上でUserモデルのカスタマイズができました!
最初のマイグレーションの時にカスタマイズを行っていないとダメという制約がありますが、
最初にカスタマイズの設定をすれば後で変更することもできると思うので、
とりあえずカスタマイズする感じになるんですかね?
なかなか大変でしたがなんとか書き切れました・・・。
最後までご覧いただきありがとうございました!