Cookie-cutter Djangoを用いる場合、最初からusersモデルが作成されているので、これを拡張します
デフォルトではusersのmodels.pyは以下のようになっています。
from django.contrib.auth.models import AbstractUser from django.db import models from django.urls import reverse from django.utils.translation import ugettext_lazy as _ class User(AbstractUser): # First Name and Last Name do not cover name patterns # around the globe. name = models.CharField(_("Name of User"), blank=True, max_length=255) def __str__(self): return self.username def get_absolute_url(self): return reverse("users:detail", kwargs={"username": self.username})
Djangoに用意されているAbstractUserを継承して作られていますが、ここではAbstractBaseUserを継承してUserを作成します。
AbstractBaseUserのほうが柔軟にカスタマイズできます。
from django.db import models from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager from django.contrib.auth.validators import UnicodeUsernameValidator from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.core.mail import send_mail from django.core import validators # Create your models here. class User(AbstractBaseUser, PermissionsMixin): SEX_CHOICE = ( ('male', 'Male'), ('female', 'Female'), ('neutral', 'Neutral'), ) AGE_CHOICE = ( ('10s', '10s'), ('20s', '20s'), ('30s', '30s'), ('40s', '40s'), ('50s', '50s'), ('60s-', 'Over 60s'), ) username_validator = UnicodeUsernameValidator() username = models.CharField( _('username'), max_length=150, unique=True, help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'), validators=[username_validator], error_messages={ 'unique': _("A user with that username already exists."), }, ) sex = models.CharField( _('sex'), max_length=7, choices=SEX_CHOICE, blank=True ) age = models.CharField( _('age'), max_length=4, choices=AGE_CHOICE, blank=True ) picture = models.ImageField( upload_to = 'users', default = 'users/default_Image.png' ) email = models.EmailField(_('email address'), blank=True) is_pro = models.BooleanField( _('pro'), default=False, help_text=_('Premium User or not.'), ) is_staff = models.BooleanField( _('staff status'), default=False, help_text=_('Designates whether the user can log into this admin site.'), ) is_active = models.BooleanField( _('active'), default=True, help_text=_( 'Designates whether this user should be treated as active. ' 'Unselect this instead of deleting accounts.' ), ) date_joined = models.DateTimeField(_('date joined'), 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 get_full_name(self): """ Return the first_name plus the last_name, with a space in between. """ full_name = '%s %s' % (self.first_name, self.last_name) return full_name.strip() def get_short_name(self): """Return the short name for the user.""" return self.first_name 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)
Adminサイトでユーザーの管理ができるようadmin.pyを記述していきます。
from django import forms from django.contrib import admin from django.contrib.auth.admin import UserAdmin as AuthUserAdmin from django.contrib.auth.forms import UserChangeForm, UserCreationForm from .models import User class MyUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = User class MyUserCreationForm(UserCreationForm): error_message = UserCreationForm.error_messages.update( {"duplicate_username": "This username has already been taken."} ) class Meta(UserCreationForm.Meta): model = User def clean_username(self): username = self.cleaned_data["username"] try: User.objects.get(username=username) except User.DoesNotExist: return username raise forms.ValidationError(self.error_messages["duplicate_username"]) @admin.register(User) class MyUserAdmin(AuthUserAdmin): form = MyUserChangeForm add_form = MyUserCreationForm fieldsets = (("User Profile", {"fields": ("picture", "username", "sex", "age", "is_pro")}),) + AuthUserAdmin.fieldsets list_display = ("username", "is_superuser", "is_staff", "is_pro") search_fields = ["username"]
マイグレーションが通れば完了です。
superuserを作成し、Userがadminサイトで確認できるかどうか見てみましょう。
python manage.py createsuperuser
python manage.py runserver
127.0.0.0:8000/adminにアクセスします。
良い感じですね。