유저 어카운트
- 장고에서 주는 기본 User를 사용하지 않고 직접 설정을 해보도록 하겠습니다.
models.py
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils.translation import gettext_lazy as _
import uuid
from django.utils import timezone
from .managers import CustomUserManager
class User(AbstractBaseUser, PermissionsMixin):
pkid = models.BigAutoField(primary_key=True, editable=False)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
username = None
email = models.EmailField(_('email address'), unique=True, db_index=True)
name = models.CharField(verbose_name=_("first_name"), max_length=50)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
class Meta:
verbose_name = (_("user"))
verbose_name_plural = (_("users"))
def __str__(self):
return self.name
managers.py
from django.contrib.auth.base_user import BaseUserManager
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _
class CustomUserManager(BaseUserManager):
def email_validator(self, email):
try:
validate_email(email)
except ValidationError:
raise ValidationError(_("You must provide a valid email address"))
def _create_user(self, email, password, name, **extra_fields):
"""Create a user with the given email and password."""
if email:
email = self.normalize_email(email)
self.email_validator(email)
else:
raise ValidationError(_("Admin Account: An email address is required"))
if not name:
raise ValueError(_("Users must submit a name"))
user = self.model(email=email, name=name, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, name, **extra_fields):
"""Create and save a regular user with the given email and password."""
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, name, **extra_fields)
def create_superuser(self, email, password, name, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get("is_staff") is not True:
raise ValueError(_("Superusers must have is_staff=True"))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superusers must have is_superuser=True"))
if not password:
raise ValueError(_("Superusers must have a password"))
return self._create_user(email, password, name, **extra_fields)
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.utils.translation import gettext_lazy as _
# from .forms import UserCreationForm, UserChangeForm
from .models import User
class UserAdmin(BaseUserAdmin):
ordering = ['created']
model = User
list_display = [
"pkid",
"id",
"email",
"name",
"is_staff",
"is_active",
]
list_display_links= ["id", "email"]
list_filter = ["email", "name", "is_staff"]
fieldsets = (
(
_("Login Credentials"),
{
"fields": (
"email",
"password",
)
},
),
(
_("Personal Information"),
{
"fields": (
"name",
)
},
),
(
_("Permissions and Groups"),
{
"fields":(
"is_active",
"is_staff",
"is_superuser"
)
}
),
(
_("Important Dates"),
{
"fields":(
"last_login",
"created",
)
}
)
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": ("email", "password1", "password2", "is_staff", "is_active")
},
),
)
search_fields = ["email", "name"]
admin.site.register(User, UserAdmin)
apps.py
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class AccountConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'account'
verbose_name = _("Account")
좀 더 심플한 버전
models.py
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
class AccountOwnerManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
"""Create a user with the given email and password."""
if not email:
raise ValueError('Email is required')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
"""Create and save a regular user with the given email and password."""
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
"""Create and save a super user with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self._create_user(email, password, **extra_fields)
class AccountOwner(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
objects = AccountOwnerManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.utils.translation import gettext_lazy as _
from .models import AccountOwner
@admin.register(AccountOwner)
class UserAdmin(DjangoUserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'),
{'fields':
('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'first_name', 'last_name', 'is_staff')
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
serializers.py
from rest_framework import serializers
from .models import AccountOwner
class AccountOwnerSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True)
class Meta:
model = AccountOwner
fields = (
'id', 'email', 'password', 'is_staff',
'is_active', 'date_joined')
def create(self, validated_data):
return AccountOwner.objects.create_user(**validated_data)