创建自定义用户模型并登录到管理者网站

用户模型的类型

在Django的用户模型中,有三种类型。
这次我们将使用AbstractBaseUser创建一个模型。

種類カラム操作特徴User不可Django標準モデル。Model作成後にカラム追加ができないため、標準の状態で使う。AbstractUser追加・変更のみカラム追加や変更は可能だが、削除ができないので、使う予定のないカラムが入ってしまう。AbstractBaseUser追加・変更・削除オリジナルのテーブルが作成可能。好きにカスタマイズできるのはこれ。
摘要:
AbstractUser模型继承了AbstractBaseUser模型和PermissionsMixin。
User模型继承了AbstractUser模型。

可以通过参考这里来确认继承的方式。

 

创建一个用于账户的应用程序

# python manage.py startapp account

在settings.py文件中写入以下内容。

INSTALLED_APPS = [
    
    'account',
]

AUTH_USER_MODEL = 'account.CustomUser'

我們將添加Account應用程式,並且描述將使用自定義用戶模型CustomUser來創建身份驗證所需的用戶模型。

建模

虽然花费了很长时间,但是我在参考了许多网站后成功地创建了这个模型。

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, UserManager, PermissionsMixin
from django.contrib.auth import validators
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils import timezone
import uuid as uuid_lib
from django.core.mail import send_mail

# コンソールでユーザーを作成するときの設定を記述する
# カスタムユーザーマネージャはBaseUserManagerを継承する
class CustomUserManager(BaseUserManager):
  # ユーザー作成時の設定
  def create_user(self, username, email, password=None):
    # username, emailが空の場合、例外エラーを出す
    if not username:
      raise ValueError('Users must have an username')
    if not email:
      raise ValueError('Users must have an email address')

    user = self.model(
      username = username,
      email = self.normalize_email(email),
    )
    user.set_password(password)
    user.save(using=self._db)
    return user

  # スーパーユーザー作成時の設定
  def create_superuser(self, username, email, password):
    user = self.create_user(
      username=username,
      email=self.normalize_email(email),
      password=password,
    )
    user.is_admin=True
    user.is_staff=True
    user.is_superuser=True
    user.save(using=self._db)
    return user

# カスタムユーザーモデルの設定
class CustomUser(AbstractBaseUser, PermissionsMixin):
    # uuidの設定
    uuid = models.UUIDField(
      default = uuid_lib.uuid4,  # デフォルト値
      primary_key = True,  # PrimaryKeyとする(1つのテーブルに1つしか設定できない)
      editable = False,  # 編集不可設定
    )

    # ユーザー名の設定
    username_validator = UnicodeUsernameValidator()  # バリデーション定義(UnicodeUsernameValidatorを使う)
    username = models.CharField(
      'ユーザー名', 
      max_length=150,  # 最大文字数
      unique=True,   # 同一カラムで重複NG
      help_text="*150文字以内で入力してくささい。",   # フォームで入力するときのヒント
      validators = [username_validator],   # 定義したバリデーションを利用する
      error_messages={
        "unique": "ユーザー名が重複しています。別のユーザー名としてください。",  # エラーメッセージ
      },
    )

    # Eメールアドレスの設定
    email = models.EmailField(
      'Eメールアドレス', 
      blank = True,  # 未入力を可とする 
    )

    # スタッフ権限の設定
    is_staff = models.BooleanField('スタッフ権限', default = False)

    # 管理者権限の設定
    is_admin = models.BooleanField('管理者権限', default = False)

    # アクティブ権限の設定
    is_active = models.BooleanField('アクティブ権限', default = True)

    # 登録日の設定
    date_joined = models.DateTimeField('登録日', default=timezone.now)

    # コンソールでユーザー作成する際の設定
    objects = CustomUserManager()

    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类以创建可自定义的用户模型。

如果您希望使用权限功能,并且AbstractBaseUser没有相关功能,那么您需要同时继承PermissionsMixin。

当调用create_user或者create_superuser方法时,会调用UserManager类中的create_user和create_superuser方法。

参考にすると、Meta类应该如下所示:https://github.com/django/django/blob/main/django/contrib/auth/models.py
class Meta:
verbose_name =’用户’
verbose_name_plural =’用户’
abstract = True #需要删除的需要删除abstract = True。当执行python manage.py make migrations时,会出现错误。将会出现以下错误:
django.core.exceptions.ImproperlyConfigured:AUTH_USER_MODEL引用尚未安装的模型’account.CustomUser’

这似乎是一个被视为抽象模型(类)而没有实体创建的错误。(参考链接):https://daeudaeu.com/django-abstractbaseuser/

创建管理员页面

您可以在admin.py文件中进行以下描述。
该文件用于描述要在Django管理网站上显示的内容。
fieldsets和fields应以列表或元组的形式进行描述。

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

@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):

    fieldsets = (
        (None, {"fields": ("username", "password")}),
        ("Personal info", {"fields": ("email",)}),
        ("Permissions", {"fields": ("is_active", "is_staff", "is_admin", "groups", "user_permissions")}),
        ("Important dates", {"fields": ("last_login", "date_joined")}),
    )

    list_display = ("username", 'email', "last_login", 'is_staff')
    search_fields = ("username", "email")
    filter_horizontal = ("groups", "user_permissions")

将其反映到数据库中

我将创建需要在数据库中进行更新的内容。

# python manage.py makemigrations

注意:由于很容易漏掉 makemigrations 命令之后的最后一个 “s”,请务必注意。如果显示为”No changes detected”或者没有出现任何错误提示,那就没问题了。

将其同步到数据库。

# python manage.py migrate

只要没有错误,就可以了。

如果已经创建了User模型,并且尝试创建自定义用户时会出现错误。
因为重新创建User模型需要执行繁琐的步骤,所以在构建数据库内容之前,我们先创建自定义用户模型。
如果要重新创建User模型,需要按照复杂的步骤进行操作。删除数据库(如果是db.sqlite3文件,删除整个文件)。

创建新的数据库。(参考:这里有关于sqlite3创建数据库的方法)

删除应用目录中migrations目录中除了__init__.py之外的文件。
※如果不小心删除了整个migrations目录,请重新创建migrations目录,并在其中创建一个空的__init__.py文件。

再次执行迁移。

※这时候,将./config/settings.py和./config/urls.py中有关admin的部分注释掉。

./config/settings.py
INSTALLED_APPS = [
# ‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘account’,
]

./config/urls.py
# from django.contrib import admin
from django.urls import path, include

urlpatterns = [
# path(‘admin/’, admin.site.urls),
path(”, include(‘account.urls’)),
]

取消注释,然后再次执行python manage.py migrate。

创建管理员用户

如果不创建用户,就无法登录后面提到的Django管理网站。可以使用python manage.py createsuperuser来创建用户。

# python manage.py createsuperuser
ユーザー名: admin
Eメールアドレス: hogehoge@mail.com
Password: 
Password (again): 
Superuser created successfully.

尝试访问Django管理网站

我将尝试访问 http://localhost:8000/admin/ 。※假如在本地主机上以8000端口公开。

我认为你将被重定向到以下URL,并显示登录页面。
http://localhost:8000/admin/login/?next=/admin/

使用先前创建的管理员用户帐户进行登录。
如果成功登录,则操作成功。

如果CSS未被应用

让我们收集管理员的静态文件。

# python manage.py collectstatic

参考资料在这里。

 

bannerAds