如果用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,增加页面,增加处理函数,