第十三章、用户自定义认证

13.1.用户自定义认证

  • class Meta:

         abstract = True   (不会创建表,只把字段继承给子类)

  • django加密方式:md5 +  盐
  • account

LADP:轻量级目录账号管理协议(集中账号管理):通过网络到LDAP服务器上进行验证

  • SSO:Single Sign on (单点登录)

(1)settings.py

AUTH_USER_MODEL = 'crm.UserProfile'

(2)crm/models.py

class UserProfileManager(BaseUserManager):def create_user(self, email, name, password=None):"""Creates and saves a User with the given email, date ofbirth 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)user.save(using=self._db)return userdef create_superuser(self, email, name, password):"""Creates and saves a superuser with the given email, date ofbirth and password."""user = self.create_user(email,password=password,name=name,)user.is_admin = Trueuser.save(using=self._db)return userclass UserProfile(AbstractBaseUser,PermissionsMixin):email = models.EmailField(verbose_name='email address',max_length=255,unique=True,)name = models.CharField(max_length=64)role = models.ManyToManyField(Role, blank=True, null=True)is_active = models.BooleanField(default=True)is_admin = models.BooleanField(default=False)is_staff = models.BooleanField(default=False)#创建用户和超级用户,关联上面的objects = UserProfileManager()USERNAME_FIELD = 'email'#必须要有的字段REQUIRED_FIELDS = ['name']def __str__(self):return self.emaildef has_perm(self, perm, obj=None):"Does the user have a specific permission?"# Simplest possible answer: Yes, alwaysreturn Truedef has_module_perms(self, app_label):"Does the user have permissions to view the app `app_label`?"# Simplest possible answer: Yes, alwaysreturn Truedef get_full_name(self):# The user is identified by their email addressreturn self.emaildef get_short_name(self):# The user is identified by their email addressreturn self.email@propertydef is_staff(self):"Is the user a member of staff?"# Simplest possible answer: All admins are staffreturn self.is_admin

(3)crm/admin.py

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashFieldfrom crm.models import UserProfileclass UserCreationForm(forms.ModelForm):"""A form for creating new users. Includes all the requiredfields, plus a repeated password."""password1 = forms.CharField(label='Password', widget=forms.PasswordInput)password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)class Meta:model = UserProfilefields = ('email', 'name')#进行验证def clean_password2(self):# Check that the two password entries matchpassword1 = self.cleaned_data.get("password1")password2 = self.cleaned_data.get("password2")if password1 and password2 and password1 != password2:raise forms.ValidationError("Passwords don't match")return password2def save(self, commit=True):# Save the provided password in hashed format#继承基类的save()user = super(UserCreationForm, self).save(commit=False)#把明文密码改成密文user.set_password(self.cleaned_data["password1"])if commit:user.save()return userclass UserChangeForm(forms.ModelForm):"""A form for updating users. Includes all the fields onthe user, but replaces the password field with admin'spassword hash display field."""#把密码改成哈希的了password = ReadOnlyPasswordHashField()class Meta:model = UserProfilefields = ('email', 'password', 'name', 'is_active', 'is_superuser')def clean_password(self):# Regardless of what the user provides, return the initial value.# This is done here, rather than on the field, because the# field does not have access to the initial valuereturn self.initial["password"]class UserProfileAdmin(BaseUserAdmin):# The forms to add and change user instancesform = UserChangeFormadd_form = UserCreationForm# The fields to be used in displaying the User model.# These override the definitions on the base UserAdmin# that reference specific fields on auth.User.list_display = ('email', 'name','is_superuser')list_filter = ('is_superuser',)fieldsets = ((None, {'fields': ('email', 'password')}),('Personal info', {'fields': ('name',)}),('Permissions', {'fields': ('is_staff','is_active','role','user_permissions','groups','is_superuser')}),)# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin# overrides get_fieldsets to use this attribute when creating a user.add_fieldsets = ((None, {'classes': ('wide',),'fields': ('email', 'name', 'password1', 'password2')}),)search_fields = ('email',)ordering = ('email',)filter_horizontal = ('role','user_permissions','groups')# Now register the new UserProfileAdmin...
admin.site.register(UserProfile, UserProfileAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
# admin.site.unregister(Group)

第十四章、万能通用权限框架设计

14.1.万能通用权限框架设计

(1)kingadmin/permission_list.py

所有权限列表

# kingamdin/permission.py

perm_dic = {# 'crm_table_index': ['table_index', 'GET', [], {}, ],  # 可以查看CRM APP里所有数据库表'crm_table_list': ['table_obj_list', 'GET', [], {}],  # 可以查看每张表里所有的数据# 'crm_table_list': ['table_obj_list', 'GET', [], {'source':0,'status':0}],  # 添加参数:只能访问来源是qq和未报名的客户'crm_table_list_view': ['table_obj_change',  'GET', [], {}],  # 可以访问表里每条数据的修改页'crm_table_list_change': ['table_obj_change', 'POST', [], {}],  # 可以对表里的每条数据进行修改'crm_table_list_add_view': ['table_obj_add ',  'GET', [], {}],  # 可以访问数据增加页'crm_table_list_add': ['table_obj_add ', 'POST', [], {}],  # 可以添加表数据

}

value[0]跟kingadmin/url.py里面的url_name一致

(2)kingadmin/permissions

# kingadmin/permissions.py# from django.core.urlresolvers import resolve
from django.urls import resolve
from django.shortcuts import render,redirect,HttpResponse
from kingadmin.permission_list import perm_dic
from django.conf import settingsdef perm_check(*args,**kwargs):#1.获取当前请求的url#2.把url解析成url_name(通过resolve)#3.判断用户是否已登录(user.is_authenticated())#3.拿url_name到permission_dict去匹配,匹配时要包括请求方法和参数#4.拿匹配到可权限key,调用user.has_perm(key)match_results = [None,]request = args[0]resolve_url_obj = resolve(request.path)#通过resolve解析出当前访问的url_namecurrent_url_name = resolve_url_obj.url_nameprint('---perm:',request.user,request.user.is_authenticated(),current_url_name)#match_flag = Falsematch_key = None#判断用户是否登录if request.user.is_authenticated() is False:return redirect(settings.LOGIN_URL)for permission_key,permission_val in  perm_dic.items():#key和value(值有四个参数): 比如 'crm_table_index': ['table_index', 'GET', [], {}, ]per_url_name = permission_val[0]per_method  = permission_val[1]perm_args = permission_val[2]perm_kwargs = permission_val[3]#如果当前访问的url_name匹配上了权限里面定义的url_nameif per_url_name == current_url_name:#url_name匹配上,接着匹配方法(post,get....)if per_method == request.method:# if not  perm_args: #if no args defined in perm dic, then set this request to passed perm#逐个匹配参数,看每个参数是否都能对应的上。args_matched = False      #for args onlyfor item in perm_args:#通过反射获取到request.xxx函数   这里request_methon_func = request.GET/request.POSTrequest_method_func = getattr(request,per_method)if request_method_func.get(item,None):   # request字典中有此参数args_matched = Trueelse:print("arg not match......")args_matched = Falsebreak          # 有一个参数不能匹配成功,则判定为假,退出该循环。因为可能有很多参数,必须所有参数都一样才匹配成功else:         # perm_dic里面的参数可能定义的就是空的,就走这里args_matched = True#匹配有特定值的参数kwargs_matched = Falsefor k,v in perm_kwargs.items():request_method_func = getattr(request, per_method)arg_val = request_method_func.get(k, None)  # request字典中有此参数print("perm kwargs check:",arg_val,type(arg_val),v,type(v))if arg_val == str(v): #匹配上了特定的参数 及对应的 参数值, 比如,需要request 对象里必须有一个叫 user_id=3的参数kwargs_matched = Trueelse:kwargs_matched = Falsebreak # 有一个参数不能匹配成功,则判定为假,退出该循环。else:kwargs_matched = Truematch_results = [args_matched,kwargs_matched]print("--->match_results ", match_results)#列表里面的元素都为真if all(match_results): #都匹配上了match_key = permission_keybreakif all(match_results):#主要是获取到app_nameapp_name, *per_name = match_key.split('_')print("--->matched ",match_results,match_key)print(app_name, *per_name)#per_obj = 例如:crm.crm_obj_listperm_obj = '%s.%s' % (app_name,match_key)print("perm str:",perm_obj)if request.user.has_perm(perm_obj):print('当前用户有此权限')return Trueelse:print('当前用户没有该权限')return Falseelse:print("未匹配到权限项,当前用户无权限")def check_permission(func):def inner(*args,**kwargs):if not perm_check(*args,**kwargs):request = args[0]return render(request,'kingadmin/page_403.html')return func(*args,**kwargs)return  inner

获取到表的名字的时候用到了 *per_name和split,具体用法解释:

(3)page_403.html

{#kingadmin/templates/kingamdin/page_403.html#}{% extends 'kingadmin/base.html' %}{% block body %}
<div class="row col-lg-offset-2"><h1 style="font-size: 200px;">403</h1><h4>You have no permission to access this page</h4>
</div>{% endblock %}

(4)crm/models.py

Meta里面加入权限

class UserProfile(AbstractBaseUser,PermissionsMixin):email = models.EmailField(verbose_name='email address',max_length=255,unique=True,)name = models.CharField(max_length=64)role = models.ManyToManyField(Role, blank=True, null=True)is_active = models.BooleanField(default=True)is_admin = models.BooleanField(default=False)is_staff = models.BooleanField(default=True)#创建用户和超级用户,关联上面的objects = UserProfileManager()USERNAME_FIELD = 'email'#必须要有的字段REQUIRED_FIELDS = ['name']def __str__(self):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 Truedef get_full_name(self):# The user is identified by their email addressreturn self.emaildef get_short_name(self):# The user is identified by their email addressreturn self.email# @property# def is_staff(self):#     "Is the user a member of staff?"#     # Simplest possible answer: All admins are staff#     return self.is_adminclass Meta:permissions = (('crm_table_list','可以查看每张表里所有的数据'),('crm_table_list_view','可以访问表里每条数据的修改页'),('crm_table_list_change','可以对表里的每条数据进行修改'),('crm_table_list_add_view','可以访问数据增加页'),('crm_table_list_add','可以添加表数据'),)

(5)kingadmin/views.py加装饰器

(6)admin后台管理权限

现在访问客户列表(还有增加修改页面)是没有权限的

必须在后台赋予权限才可以

再访问就可以了

14.2.自定义权限钩子实现

只允许用户访问自己创建的数据,比如只允许销售访问自己创建的客户:

(1)kingadmin/permission_list.py

'crm_table_list': ['table_obj_list', 'GET', [], {},permission_hook.view_my_own_customers], 

(2)kingadmin/permission_hook.py

# kingadmin/permission_hook.pydef view_my_own_customers(request):#当前登录的用户id 等于客户的顾问的id(销售创建客户的时候,顾问就是销售自己)#实现销售只能看自己的客户功能if str(request.user.id) == request.GET.get('consultant'):return Trueelse:return False

(3)kingadmin/permissions.py

现在销售就只能看到自己创建的客户了

这样,万通通用的权限框架就开发完毕了,权限的控制可大可小,而且想要移植到其它django项目时, 唯一需要改的,就是配置好perm_dic里的权限条目!

转载于:https://www.cnblogs.com/derek1184405959/p/8995191.html

CRM客户关系管理系统(十三)相关推荐

  1. Java项目:CRM客户关系管理系统(java+Springboot+maven+mysql)

    源码获取:博客首页 "资源" 里下载! Springboot项目CRM客户关系管理系统: 系统实现了CRM客户关系系统的基本功能,主要有看板(当月参与的业务机会.当月转化情况.将要 ...

  2. Myesclipe+SSH+jsp+mysql+tomcate实现一个简单的CRM客户关系管理系统

    导读: CRM客户关系管理系统的目的通过客户管理,产品管理,系统管理等功能同客户建立联并收集客户信息,此基础上满足客户"一对一"个性化服务.同时信息在企业的流程上得以流转,让客户得 ...

  3. 前端做CRM管理系统是做什么_代办行业的CRM客户关系管理系统应该是什么样子的?...

    随着互联网的深耕细化,很多企业也在不断优化自己的办公方式,以优化企业的办公流程,提高企业的办事效率.因此实现办公自动化,或者说实现数字化办公就需要逐渐提上日程. 今天给大家讲讲可以帮助代办行业实现办公 ...

  4. crm客户管理系统源码_公司crm客户关系管理系统的功能

    企业的最终目标是服务好客户,赢得客户的青睐.为了实现这一目标,除了扎实的产品和优秀的团队,我们还必须选择科学的管理体系来帮助企业实现这一最终目标.这个系统就是公司crm客户关系管理系统,点镜SCRM公 ...

  5. 保险行业CRM客户关系管理系统解决方案

    近几年保险行业进入快速发展的阶段,各类保险产品引领各类广大市场.不过也是一个具有经营风险的金融行业,业内人士认为在借助保险行业CRM客户关系管理系统可以大大的把握住客户关系,有助于保险行业的风险管理机 ...

  6. JAVA+SSM+MySql CRM客户关系管理系统(附带源码)

    一.前言 利用软件.硬件和网络技术,为企业建立一个客户信息收集.管理.分析和利用的信息系统.以客户数据的管理为核心,记录企业在市场营销和销售过程中和客户发生的各种交互行为,以及各类有关活动的状态,提供 ...

  7. CRM客户关系管理系统源码

    项目介绍: 这是一个基于Springboot+MySql实现的CRM客户关系管理系统. 技术特点: SpringBoot+MyBatis+Maven+Jquery+Bootstrap 推荐环境配置: ...

  8. 开源项目-CRM客户关系管理系统

    哈喽,大家好,今天给大家带来一个开源系统-CRM客户关系管理系统 主要功能包括客户管理,客户流失,销售机会,客户关怀等模块 系统开发环境以及版本 操作系统: Windows_7 集成开发工具: Ecl ...

  9. Java Web项目源代码|CRM客户关系管理系统项目实战(Struts2+Spring+Hibernate)解析+源代码+教程

    客户关系管理 (CRM) CRM一般指客户关系管理 客户关系管理是指企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方式,向客户提供创新 ...

  10. Asp.Net CRM客户关系管理系统

    Asp.Net CRM客户关系管理系统 CRM是为帮助企业快速成长发展而开发的一款优秀的CRM客户关系管理系统,能帮助您管理客户与销售,能协同进行工作,并能方便的进行二次开发与扩 展,是您企业信息化进 ...

最新文章

  1. Java项目:考试管理系统(java+Springboot+Maven+Jpa+Vue+Mysql)
  2. 做过十几年程序员,作为当今全世界顶级产品经理,出版第二部重磅作品《启示录2》...
  3. linux 内核中基于netfilter的编译选项
  4. 关于敏捷规划的微信对话
  5. 直击「神策 2021 数据驱动大会」五大论坛,精彩不断
  6. Please make sure you have the correct access rights and the repository exists.报错问题
  7. C语言: ---gdb查看内存和寄存器内容
  8. 4键电子手表说明书_数字S1系统7寸门口主机操作说明书
  9. 案例学习BlazeDS+Spring之三InSync01查找联系人
  10. 女孩必读:打死不能嫁的36种男人
  11. 使用V-ASSISTANT软件配置V90伺服驱动器参数的具体步骤详解
  12. 数据库1_五大主流数据库模型
  13. react-ant-design输入框输入时拼音字符触发onChange事件(防抖)处理
  14. ASP.NET 学习笔记 之 MasterPageFile母版页
  15. 南大软院大神养成计划--CSS网页布局
  16. r7 6700g核显相当于什么显卡 锐龙r76700g性能怎么样
  17. 你学了多久 Python 并能正式工作?
  18. 《爱乐之城》:两个追梦人令人唏嘘又动容的爱情故事
  19. 使用c语言实现复数运算的程序,用C语言实现的复数运算程序设计
  20. Filament加载并渲染glTF模型

热门文章

  1. 改变openssl的环境变量linux,ECS Linux 安装配置openssl的具体过程
  2. (1)hibenrate入门例子
  3. 第04篇 JDK版本导致Unsupported major.minor version 52.0 error
  4. UDP 无连接上机案例3.4
  5. Windows下Maven的安装与配置
  6. centos中的配置文件
  7. AdapterView及其子类之二:使用ListActivity及ArrayAdapter创建列表
  8. 终端、虚拟控制台与伪终端
  9. TensorFlow学习笔记(二十八)CNN的9大模型之AlexNet
  10. Elasticsearch如何关掉服务