django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'sso.User' that has not been installed


我出現的問題是在一個main.py 互相引用了user

look my demo:

from django.db import models
#導入時間域
from django.utils import timezone
# 懶加載可翻譯
from django.utils.translation import gettext_lazy as _
# 引入 AbstractUser表,高級的功能/密碼自動加密/檢查密碼
from django.contrib.auth.models import AbstractUser
# 導入自定義重寫注冊用戶的管理類
from sso.main import CustomUserManager


#基類
class BaseModel(models.Model):

    #創建時間
    create_time = models.DateTimeField(default=timezone.now, null=True)

    class Meta:
        abstract = True


# 重寫了原來User模型的表結構,所以必須第一次migrate前就先定義好
class User(AbstractUser):
    uid = models.BigIntegerField(primary_key=True, auto_created=True, unique=True, verbose_name=_('id全局標識'))
    email = models.CharField(unique=True, max_length=100, error_messages={'unique': _('此郵箱已被注冊')})
    # 額外的
    mobile = models.CharField(unique=True, max_length=20, verbose_name=_('手機號'))
    avatar = models.ImageField(
        upload_to='avatar',  #保存上傳文件的目錄
        verbose_name='頭像',  #admin顯示文字
        null=True,
        blank=True,
    )
    # 頭像本地化處理
    avatar_url = models.URLField(
        null=True,
        blank=True,
        verbose_name='頭像地址',
    )
    last_login_ip = models.CharField(max_length=40, blank=True, null=True)
    last_changepwd_time = models.DateTimeField(default=timezone.now, blank=True, null=True)
    original_pwd_change = models.PositiveIntegerField(default=0)

    USERNAME_FIELD = 'email'  # 身份驗證字段指向email,而不是原來的username
    REQUIRED_FIELDS = ['username']  # 注冊admin用戶提示選項

    # 重新定義Manager對象,在創建user的時候使用
    # email 和 password,而不是使用username和password
    objects = CustomUserManager()

    class Meta:
        managed = False
        db_table = 'authuser'
        verbose_name = '用戶'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.email


# 基於角色的權限管理,使用django-admin自帶表,把group當作角色

接着問題來了,attention:

objects = CustomUserManager()

Yes,你必須在單獨的.py中構造它,切記不能再里面引用User模型!!!

Like This Demo:

# Create your views here.
# 引用用戶注冊管理類
from django.contrib.auth.models import UserManager
# 雪花發號器
from sso.db.snowflake_tool import snowflakeid

__all__ = ('CustomUserManager', )


# 自定義重寫注冊用戶的管理類
class CustomUserManager(UserManager):
    use_in_migrations = True

    print('# # # Override the registered user management class UserManager to `CustomUserManager`')

    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not email:
            raise ValueError('The given email must be set')
        # 使用雪花發號器
        uid = snowflakeid()
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(uid=uid, username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user


最后在admin.py,你可以寫上有關它的擴展,
Like This Demo:
# Register your models here.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
# 重新導入擴展后的user表
# from sso.models import User
# from django2education.settings import AUTH_USER_MODEL as User
from django.contrib.auth import get_user_model
User = get_user_model()
# 導入默認settings.AUTH_USER_MODEL
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q, F
from sso.hashers import md5

admin.site.register(User, UserAdmin)


# 自定義用戶身份認證類方法authenticate,配置到settings.py
# 支持用戶名/手機/郵箱的用戶認證
class CustomBackend(ModelBackend):
    print("# # # The custom user authentication class `CustomBackend`")

    @staticmethod
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username=username) | Q(email=username) | Q(mobile=username))
            # 統一前后端密碼:由於獲取vue前端的輸入密碼是已用md5加密,獲取django-admin后台的輸入密碼是未加密
            password = md5(password) if len(password) < 32 else password
            if user.check_password(password):
                return user
        except Exception as e:
            print(str(e))
            return None

    def get_user(self, uid):
        try:
            return User.objects.get(id=uid)
        except Exception:
            return None



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM