zoukankan      html  css  js  c++  java
  • 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


  • 相关阅读:
    艾伟_转载:基于.NET平台的Windows编程实战(三)—— 项目的创建及主界面的设计 狼人:
    艾伟_转载:C# Design Patterns (2) Strategy 狼人:
    艾伟_转载:C# Design Patterns (5) Prototype 狼人:
    艾伟_转载:正则表达式30分钟入门教程 狼人:
    艾伟_转载:WCF安全之EndPointIdentity 狼人:
    艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现 狼人:
    艾伟_转载:.NET平台上的Memcached客户端介绍 狼人:
    艾伟_转载:关于.NET中的循环引用 狼人:
    艾伟_转载:VS 2008快捷键 狼人:
    艾伟_转载:Regex.Replace 方法的性能! 狼人:
  • 原文地址:https://www.cnblogs.com/justblue/p/13178219.html
Copyright © 2011-2022 走看看