似乎在Django中应该创建自定义用户

我真的需要做吗?

在[Django官方文档]中提到,在项目开始时使用自定义用户模型。

对于开始新项目时,即使默认的用户也足够使用,我们强烈建议创建自定义的用户模型。

听说是这样的。

我們需要繼承其中一個類別 “django.contrib.auth.base_user.AbstractBaseUser” 或 “django.contrib.auth.models.AbstractUser” 來建立自定義的使用者。但這次我們將選擇”AbstractBaseUser”,雖然它被認為更具有彈性,但也更難一些。

这次做的东西

我已将以下内容放在【github】gaku3601/django_customuser。

马上试一下

创建PJ和账户应用程序。

$ django-admin startproject customUserPJ .
$ python manage.py startapp account

由于添加了一个应用程序,所以需要在PJ的设置中添加该应用程序的补充。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account', 追記
]

另外,为了将新建的应用程序中的User模型(稍后创建)设置为默认的认证用户模型,也需要添加以下内容。

AUTH_USER_MODEL = 'account.User'

我們將建立用戶模型。這只是將幾乎完全複製django/django【models.py】中的AbstractUser類和UserManager類用於使用的內容。這次的目的是建立自訂用戶的基礎,因此不進行項目添加或編輯。

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.core.mail import send_mail
from django.contrib.auth.base_user import BaseUserManager

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.
    Username and password are required. Other fields are optional.
    """
    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."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    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')
        #abstract = True # ここを削除しないといけないことを忘れない!!!!!!!!!!

    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.py文件的内容如下。

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

对已创建的user模型进行migration的创建和应用。

$ python manage.py makemigrations
$ python manage.py migrate

创建管理员的超级用户,并启动系统。

$ python manage.py createsuperuser
$ python manage.py runserver

使用浏览器访问管理页面并进行确认。

スクリーンショット 2019-02-21 11.13.56.png

默认情况下,身份验证和授权中的Users已被移除,并新增了名为ACCOUNT的用户组?

最后, 投自.

昨天我尝试了一个刚学Python的新手在Django中实现JWT令牌认证。然后,我在默认的「身份验证和授权」中使用默认的Users模型被阻止编辑,这让我感到非常不舒服。然而,通过创建和使用自定义用户,我可以自由定义用户模型,从而消除了这种不适感。

只是,继承django.contrib.auth.base_user.AbstractBaseUser来创建User模型是一个相当困难的任务,所以如果能稍微简单点就好了,我会感到很开心的。(希望有人可以帮忙提出合并请求。)

文献引用

Django用户的自定义方式

广告
将在 10 秒后关闭
bannerAds