【Cookiecutter-Djangoで作るWebアプリ】User modelの拡張

Django

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にアクセスします。

良い感じですね。

タイトルとURLをコピーしました