15-crm项目-kingadmin,自定义用户认证

如果用django自带的表,会有局限性,

你每次新建用户的时候需要建两个表的内容,user,userProfile,也就是跑到两个表建内容,没法直接在user中创建,

你每次调用的时候,不能直接写request.user.name,必须要request.user.userProfile.name才可以,

 

怎么办?

所以我们要重写这个用户认证,之前只是扩展,是通过继承的方式的,实际是通过一张新表的方式,

现在我们只要一张表,只有一个userProfile表了,

生产上的也都是对django自带的用户认证做了更改

 

怎么重写?

class UserProfile(AbstractBaseUser, PermissionsMixin):
    '''账号表'''
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
        null=True
    )
    password = models.CharField(_('password'), max_length=128,
                                help_text=mark_safe('''<a href='password/'>修改密码</a>'''))
    name = models.CharField(max_length=32)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    roles = models.ManyToManyField("Role", blank=True)
    objects = UserProfileManager()  -----这个就是指定了如何创建用户,

    stu_account = models.ForeignKey("Customer", verbose_name="关联学员账号", blank=True, null=True,
                                    help_text="只有学员报名后方可为其创建账号")
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):  # __unicode__ on Python 2
        return self.email

    # def has_perm(self, perm, obj=None):
    #     "Does the user have a specific permission?"
    #     # Simplest possible answer: Yes, always
    #     return True
    #
    # def has_module_perms(self, app_label):
    #     "Does the user have permissions to view the app `app_label`?"
    #     # Simplest possible answer: Yes, always
    #     return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_active

    class Meta:
        permissions = (('can_fuck_him_to_death', '弄死小虎逼'),
                       ('can_access_my_course', '可以访问我的课程'),
                       ('can_access_customer_list', '可以访问客户列表'),
                       ('can_access_customer_detail', '可以访问客户详细'),
                       ('can_access_studyrecords', '可以访问学习记录页面'),
                       ('can_access_homework_detail', '可以访问作业详情页面'),
                       ('can_upload_homework', '可以交作业'),
                       ('access_kingadmin_table_obj_detail', '可以访问kingadmin每个表的对象'),
                       ('change_kingadmin_table_obj_detail', '可以修改kingadmin每个表的对象'),
                       )

 

注册的时候表也要改变一下,admin类里面的内容字段也要改变一下,

接下来要生成这个表,中间可能会出现问题,需要解决,

 

问题:

这个表是你写的,django怎么知道这是一个用户表呢?,现在django不知道,所以你要做配置,

在settings里面做配置,

配置之后还需要迁移一下数据库,会把django自带的表删除,

AUTH_USER_MODEL = 'crm.UserProfile'

 

但是这个时候创建用户的时候报错了,就是这个model用户表有了,但是怎么使用这个表创建用户,这是需要你自己定义的,

这个类做了什么呢?

创建用户,

创建超级用户,

class UserProfileManager(BaseUserManager):
    def create_user(self, email, name, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            name=name,
        )

        user.set_password(password)  ----保存密码,这是要加密存储的,md5加密,但是这个要加盐的,md5是不可逆的,
        self.is_active = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, name, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            password=password,
            name=name,
        )
        user.is_active = True
        user.is_admin = True
        user.save(using=self._db)
        return user

 

这样我们自己写的king_admin创建用户的时候也是需要填写用户名密码的,这样就可以了

但是还缺少修改密码,但是不着急,后面写,

 

修改密码:

首先加一个入口:

class UserProfile(AbstractBaseUser, PermissionsMixin):
    '''账号表'''
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
        null=True
    )
    password = models.CharField(_('password'), max_length=128,
                                help_text=mark_safe('''<a href='password/'>修改密码</a>'''))
    name = models.CharField(max_length=32)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    roles = models.ManyToManyField("Role", blank=True)
    objects = UserProfileManager()

    stu_account = models.ForeignKey("Customer", verbose_name="关联学员账号", blank=True, null=True,
                                    help_text="只有学员报名后方可为其创建账号")
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):  # __unicode__ on Python 2
        return self.email

    # def has_perm(self, perm, obj=None):
    #     "Does the user have a specific permission?"
    #     # Simplest possible answer: Yes, always
    #     return True
    #
    # def has_module_perms(self, app_label):
    #     "Does the user have permissions to view the app `app_label`?"
    #     # Simplest possible answer: Yes, always
    #     return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_active

    class Meta:
        permissions = (('can_fuck_him_to_death', '弄死小虎逼'),
                       ('can_access_my_course', '可以访问我的课程'),
                       ('can_access_customer_list', '可以访问客户列表'),
                       ('can_access_customer_detail', '可以访问客户详细'),
                       ('can_access_studyrecords', '可以访问学习记录页面'),
                       ('can_access_homework_detail', '可以访问作业详情页面'),
                       ('can_upload_homework', '可以交作业'),
                       ('access_kingadmin_table_obj_detail', '可以访问kingadmin每个表的对象'),
                       ('change_kingadmin_table_obj_detail', '可以修改kingadmin每个表的对象'),
                       )

 

增加url路由:

from django.conf.urls import url,RegexURLPattern,RegexURLResolver
from king_admin import views

urlpatterns = [
    url(r'^$', views.index,name="table_index"),
    url(r'^(\w+)/(\w+)/$', views.display_table_objs,name="table_objs"),
    url(r'^(\w+)/(\w+)/(\d+)/change/$', views.table_obj_change,name="table_obj_change"),
    url(r'^(\w+)/(\w+)/(\d+)/change/password/$', views.password_reset,name="password_reset"),
    url(r'^(\w+)/(\w+)/(\d+)/delete/$', views.table_obj_delete,name="obj_delete"),
    url(r'^(\w+)/(\w+)/add/$', views.table_obj_add,name="table_obj_add"),

]

 

 

然后增加处理函数:

@login_required
def password_reset(request,app_name,table_name,obj_id):

    admin_class = king_admin.enabled_admins[app_name][table_name]
    model_form_class = create_model_form(request,admin_class)

    obj = admin_class.model.objects.get(id=obj_id)
    errors = {}
    if request.method == "POST":
        _password1 = request.POST.get("password1")
        _password2 = request.POST.get("password2")

        if _password1 == _password2:
            if len(_password2) >5:
                obj.set_password(_password1)
                obj.save()
                return redirect(request.path.rstrip("password/"))

            else:
                errors["password_too_short"] = "must not less than 6 letters"
        else:
            errors['invalid_password'] = "passwords are not the same"
    return render(request,'king_admin/password_reset.html', {"obj":obj,'errors':errors})

 

点击跳转到修改密码的页面,

{%  extends 'king_admin/table_index.html' %}
{% load tags %}


{% block container %}

<div class="row">
    <div class="panel panel-info">
      <div class="panel-heading">
        <h3 class="panel-title">重置用户[{{ obj.name }}]密码</h3>
      </div>
      <div class="panel-body col-lg-5">

          <form class="form-horizontal" role="form" method="post"> {% csrf_token %}
              <div class="form-group">
                <label  class="col-sm-2 control-label" style="font-weight: normal">
                    用户名
                </label>
                <div class="col-sm-6">
                    <input class="form-control" type="text" value="{{ obj.email }}" disabled>
                </div>
              </div>
              <div class="form-group">
                <label  class="col-sm-2 control-label" style="font-weight: normal">
                    密码
                </label>
                <div class="col-sm-6">
                    <input class="form-control" type="password" name="password1">
                </div>
              </div>
              <div class="form-group">
                <label  class="col-sm-2 control-label" style="font-weight: normal">
                    密码(重复)
                </label>
                <div class="col-sm-6">
                    <input class="form-control" type="password" name="password2">
                </div>
              </div>
              <div>
                  <ul style="color: red">
                      {% for k,v in errors.items %}
                      <li>{{ k }}:{{ v }}</li>
                      {% endfor %}
                  </ul>


              </div>
              <input type="submit"  class="btn btn-info center-block" value="提交">
          </form>

      </div>

    </div>
</div>
{% endblock %}

 

所以整个的套路就是增加model,增加入口url,增加页面,增加处理函数,

 

posted @ 2020-09-24 20:49  技术改变命运Andy  阅读(198)  评论(0编辑  收藏  举报