admin的自定制开发
18.django实现自定义用户认证
1 from django.db import models 2 from django.contrib.auth.models import ( 3 BaseUserManager, AbstractBaseUser 4 ) 5 6 7 class MyUserManager(BaseUserManager): 8 def create_user(self, email, date_of_birth, password=None): 9 """ 10 Creates and saves a User with the given email, date of 11 birth and password. 12 """ 13 if not email: 14 raise ValueError('Users must have an email address') 15 16 user = self.model( 17 email=self.normalize_email(email), 18 date_of_birth=date_of_birth, 19 ) 20 21 user.set_password(password) 22 user.save(using=self._db) 23 return user 24 25 def create_superuser(self, email, date_of_birth, password): 26 """ 27 Creates and saves a superuser with the given email, date of 28 birth and password. 29 """ 30 user = self.create_user( 31 email, 32 password=password, 33 date_of_birth=date_of_birth, 34 ) 35 user.is_admin = True 36 user.save(using=self._db) 37 return user 38 39 40 class MyUser(AbstractBaseUser): 41 email = models.EmailField( 42 verbose_name='email address', 43 max_length=255, 44 unique=True, 45 ) 46 date_of_birth = models.DateField() 47 is_active = models.BooleanField(default=True) 48 is_admin = models.BooleanField(default=False) 49 50 objects = MyUserManager() 51 52 USERNAME_FIELD = 'email' 53 REQUIRED_FIELDS = ['date_of_birth'] 54 55 def __str__(self): 56 return self.email 57 58 def has_perm(self, perm, obj=None): 59 "Does the user have a specific permission?" 60 # Simplest possible answer: Yes, always 61 return True 62 63 def has_module_perms(self, app_label): 64 "Does the user have permissions to view the app `app_label`?" 65 # Simplest possible answer: Yes, always 66 return True 67 68 @property 69 def is_staff(self): 70 "Is the user a member of staff?" 71 # Simplest possible answer: All admins are staff 72 return self.is_admin
1 from django import forms 2 from django.contrib import admin 3 from django.contrib.auth.models import Group 4 from django.contrib.auth.admin import UserAdmin as BaseUserAdmin 5 from django.contrib.auth.forms import ReadOnlyPasswordHashField 6 7 from customauth.models import MyUser 8 9 10 class UserCreationForm(forms.ModelForm): 11 """A form for creating new users. Includes all the required 12 fields, plus a repeated password.""" 13 password1 = forms.CharField(label='Password', widget=forms.PasswordInput) 14 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) 15 16 class Meta: 17 model = MyUser 18 fields = ('email', 'date_of_birth') 19 20 def clean_password2(self): 21 # Check that the two password entries match 22 password1 = self.cleaned_data.get("password1") 23 password2 = self.cleaned_data.get("password2") 24 if password1 and password2 and password1 != password2: 25 raise forms.ValidationError("Passwords don't match") 26 return password2 27 28 def save(self, commit=True): 29 # Save the provided password in hashed format 30 user = super().save(commit=False) 31 user.set_password(self.cleaned_data["password1"]) 32 if commit: 33 user.save() 34 return user 35 36 37 class UserChangeForm(forms.ModelForm): 38 """A form for updating users. Includes all the fields on 39 the user, but replaces the password field with admin's 40 password hash display field. 41 """ 42 password = ReadOnlyPasswordHashField() 43 44 class Meta: 45 model = MyUser 46 fields = ('email', 'password', 'date_of_birth', 'is_active', 'is_admin') 47 48 def clean_password(self): 49 # Regardless of what the user provides, return the initial value. 50 # This is done here, rather than on the field, because the 51 # field does not have access to the initial value 52 return self.initial["password"] 53 54 55 class UserAdmin(BaseUserAdmin): 56 # The forms to add and change user instances 57 form = UserChangeForm 58 add_form = UserCreationForm 59 60 # The fields to be used in displaying the User model. 61 # These override the definitions on the base UserAdmin 62 # that reference specific fields on auth.User. 63 list_display = ('email', 'date_of_birth', 'is_admin') 64 list_filter = ('is_admin',) 65 fieldsets = ( 66 (None, {'fields': ('email', 'password')}), 67 ('Personal info', {'fields': ('date_of_birth',)}), 68 ('Permissions', {'fields': ('is_admin',)}), 69 ) 70 # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin 71 # overrides get_fieldsets to use this attribute when creating a user. 72 add_fieldsets = ( 73 (None, { 74 'classes': ('wide',), 75 'fields': ('email', 'date_of_birth', 'password1', 'password2')} 76 ), 77 ) 78 search_fields = ('email',) 79 ordering = ('email',) 80 filter_horizontal = () 81 82 # Now register the new UserAdmin... 83 admin.site.register(MyUser, UserAdmin) 84 # ... and, since we're not using Django's built-in permissions, 85 # unregister the Group model from admin. 86 admin.site.unregister(Group)
1 AUTH_USER_MODEL = 'customauth.MyUser'
19.king admin实现自定义的用户认证
修改密码:
1 class UserProfile(AbstractBaseUser,PermissionsMixin): 2 email = models.EmailField( 3 verbose_name='email address', 4 max_length=255, 5 unique=True, 6 ) 7 name =models.CharField(max_length=32) 8 password = models.CharField(_('password'), max_length=128,help_text=mark_safe("""<a href='password/'>修改密码</a>""")) 9 is_active = models.BooleanField(default=True) 10 is_admin = models.BooleanField(default=False) 11 12 objects = UserProfileManager() 13 14 USERNAME_FIELD = 'email' 15 REQUIRED_FIELDS = ['name'] 16 17 def __str__(self): 18 return self.email 19 20 def has_perm(self, perm, obj=None): 21 "Does the user have a specific permission?" 22 # Simplest possible answer: Yes, always 23 return True 24 25 def has_module_perms(self, app_label): 26 "Does the user have permissions to view the app `app_label`?" 27 # Simplest possible answer: Yes, always 28 return True 29 30 @property 31 def is_staff(self): 32 "Is the user a member of staff?" 33 # Simplest possible answer: All admins are staff 34 return self.is_admin
1 def password_reset(request,app_name,table_name,obj_id): 2 """修改密码""" 3 admin_class = king_admin.enabled_admins[app_name][table_name] 4 model_class_form = create_model_form(request, admin_class) 5 obj = admin_class.model.objects.get(id=obj_id) 6 7 errors={} 8 if request.method == "POST": 9 _password1 = request.POST.get("password1") 10 _password2 = request.POST.get("password2") 11 12 if _password1 == _password2: 13 if len(_password2)>5: 14 obj.set_password(_password1) 15 obj.save() 16 return redirect(request.path.rstrip("password/")) 17 else: 18 errors["password_too_short"] = "must not less than 6 charts" 19 else: 20 errors["invalid_password"] = "passwords is not same" 21 22 return render(request,"king_admin/password_reset.html",{"obj":obj,"errors":errors})
1 {% extends "king_admin/table_index.html" %} 2 {% load tags %} 3 {% block container %} 4 5 <div class="row"> 6 <div class="panel panel-info"> 7 <div class="panel-heading"> 8 <h3 class="panel-title">重置用户{{ obj.name }}密码</h3> 9 </div> 10 11 <div class="panel-body"> 12 <form class="form-horizontal" role="form" method="post"> 13 {% csrf_token %} 14 <div class="form-group"> 15 <label class="col-sm-2 control-label" style="font-weight: normal"> 16 用户名 17 </label> 18 <div class="col-sm-4"> 19 <input class="form-contral" type="text" value="{{ obj.email }}" disabled /> 20 </div> 21 </div> 22 <div class="form-group"> 23 <label class="col-sm-2 control-label" style="font-weight: normal"> 24 密码 25 </label> 26 <div class="col-sm-4"> 27 <input class="form-contral" type="password" name="password1" /> 28 </div> 29 </div> 30 <div class="form-group"> 31 <label class="col-sm-2 control-label" style="font-weight: normal"> 32 密码(重置) 33 </label> 34 <div class="col-sm-4"> 35 <input class="form-contral" type="password" name="password2" /> 36 </div> 37 </div> 38 39 <div> 40 <ul style="color: red"> 41 {% for k,v in errors.items %} 42 <li>{{ k }}{{ v }}</li> 43 {% endfor %} 44 </ul> 45 </div> 46 <input type="submit" value="提交" class="btn btn-info" /> 47 </form> 48 49 50 </div> 51 </div> 52 </div> 53 54 55 {% endblock %}
取消某一字段:
class Meta:
model = admin_class.model
fields = "__all__"
exclude = admin_class.modelform_exclude_fields #设置取消字段的别名
class UserProfileAdmin(BaseAdmin):
list_display = ["email","name"]
filter_horizontal = ("groups","user_permissions")
modelform_exclude_fields=["last_login",]
20.前段显示数据库中不存在的用户自定义数据字段
1 class CustomerAdmin(BaseAdmin): 2 list_display = ["id","qq","name","source","consult_course","date","consultant","enroll"] 3 4 5 def enroll(self):#数据库中不存在的字段 6 # print("enroll",self) 7 return """<a href=%s/enrollment>报名</a>"""%self.instance.id
1 def bulid_table_row(request,obj,admin_class): 2 row_ele = "" 3 for index,column in enumerate(admin_class.list_display): 4 try: 5 field_obj = obj._meta.get_field(column) 6 if field_obj.choices: 7 column_date = getattr(obj,"get_%s_display" % column)() 8 else: 9 column_date = getattr(obj,column) 10 11 if type(column_date).__name__ == "datetime": 12 column_date = column_date.strftime("%Y-%m-%d %H:%M:%S") 13 14 if index == 0: 15 column_date = "<a href='{request_path}{obj_id}/change/'>{date}</a>".format(request_path=request.path, 16 obj_id=obj.id,date=column_date) 17 18 except FieldDoesNotExist as e: 19 if hasattr(admin_class,column): 20 column_func = getattr(admin_class,column) 21 admin_class.instance =obj 22 admin_class.request = request 23 column_date = column_func() 24 25 row_ele += "<td>%s</td>" % column_date 26 return mark_safe(row_ele)
字段全部显示成verbose_name为汉字
1 def bulid_table_header_column(column,orderby_key,filter_condtions,admin_class): 2 filters = "" 3 for k, v in filter_condtions.items(): 4 filters += "&%s=%s" % (k, v) 5 6 ele = """<th><a href="?{filters}&o={orderby_key}">{column}</a>{icon}</th>""" 7 # print(orderby_key,column) 8 # < span class ="glyphicon glyphicon-arrow-down" aria-hidden="true" > < / span > 9 if orderby_key: 10 if orderby_key.startswith("-"): 11 icon = """<span class ="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>""" 12 else: 13 icon = """<span class ="glyphicon glyphicon-arrow-down" aria-hidden="true"></span>""" 14 15 16 if orderby_key.strip("-") == column : # 确定排序的是那个字段 17 orderby_key = orderby_key 18 else: 19 orderby_key =column 20 icon="" 21 else: 22 orderby_key = column 23 icon="" 24 try:#把字段转化成汉字(verbose_name) 25 column_verbose_name = admin_class.model._meta.get_field(column).verbose_name 26 except FieldDoesNotExist as e: 27 column_verbose_name = getattr(admin_class,column).display_name 28 29 res = ele.format(orderby_key=orderby_key,column=column_verbose_name,icon=icon,filters=filters) 30 return mark_safe(res)
21.crm的用户认证登录
首先要有登录界面login
1 {% extends "base.html" %} 2 {% block body %} 3 4 5 <div class="container col-lg-offset-4"> 6 <form class="form-signin col-lg-3 " method="post" role="form"> 7 {% csrf_token %} 8 <h2 class="form-signin-heading">Please sign in</h2> 9 <label for="inputEmail" class="sr-only">Email address</label> 10 <input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> 11 <label for="inputPassword" class="sr-only">Password</label> 12 <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> 13 {% if errors %} 14 <span style="color: red">{{ errors.error }}</span> 15 {% endif %} 16 <div class="checkbox"> 17 <label> 18 <input type="checkbox" value="remember-me"> Remember me 19 </label> 20 </div> 21 <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> 22 </form> 23 </div> <!-- /container --> 24 {% endblock %}
url
1 path('account/login/', views.acc_login), 2 path('account/logout/',views.acc_logout,name='acc_logout'),
views
1 from django.shortcuts import render,HttpResponse,redirect 2 from django.contrib.auth import login,authenticate,logout 3 4 5 6 def acc_login(request): 7 8 errors={} 9 if request.method == "POST": 10 _email = request.POST.get("email") 11 _password = request.POST.get("password") 12 13 user = authenticate(username=_email,password=_password) 14 print(user) 15 if user: 16 login(request,user) 17 next_url = request.GET.get("next","/crm/index/") 18 return redirect(next_url) 19 else: 20 errors["error"]="Wrong email or password" 21 22 23 return render(request,"login.html",{"errors":errors}) 24 25 26 27 def acc_logout(request): 28 29 logout(request) 30 31 return redirect("/account/login/")
在用户未登录情况下是不允许访问其他页面的,这要在其他页面上增加装饰器
from django.contrib.auth.decorators import login_required
@login_required
def ***
添加user_name的下拉框
1 <li class="dropdown open"> 2 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">{{ request.user.name }} <span class="caret"></span></a> 3 <ul class="dropdown-menu"> 4 <li><a href="#">配置</a></li> 5 <li><a href="{% url 'acc_logout' %}">注销</a></li> 6 </ul> 7 </li>
从其他页面注销后跳转页面设置
1 LOGIN_URL = "/account/login/"
1 if user: 2 login(request,user) 3 next_url = request.GET.get("next","/crm/index/") #跳转到其他页面 4 return redirect(next_url) 5 else: 6 errors["error"]="Wrong email or password"
效果:
######################################################