一:admin下的权限了解

推文:如何正确使用 Django的User Model

(一)默认权限表是在自带auth模块,中permission表中

可以使用has_perm方法获取用户是否有这个权限

(二)Django自定义权限

(1)添加表

from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser,PermissionsMixin
#BaseUserManager  用户管理基类,用于创建用户
#AbstractBaseUser 抽象类,声明一些必须字段,不会自己生产表,继承的子类才会,主要内容:class Meta abstract=True
#PermissionMixin 权限管理类,也是抽象类
) class MyUserManager(BaseUserManager):   #用于创建用户,需要在settings文件中声明
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)
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_superuser = True
user.save(using=self._db)
return user class UserProfile(AbstractBaseUser,PermissionsMixin):  
email = models.EmailField(
verbose_name='email address',
max_length=,
unique=True,
)
name = models.CharField(max_length=)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
# is_admin = models.BooleanField(default=False)  #其中is_admin没有作用,is_superuser才是设置超级用户
role = models.ManyToManyField("Role",blank=True) #,null=Truenull has no effect on ManyToManyField.,null对于manytomanyfield无作用,会报警 objects = MyUserManager() #用户管理类和自定义用户表关联 USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name'] def __str__(self):
return self.email def get_full_name(self):
return self.email def get_short_name(self):
return self.email class Meta:
permissions = (  #用于管理权限条目
('自定义权限名','解释'),
)

(2)settings文件中设置

AUTH_USER_MODEL = 'repository.UserProfile' #上面的值表示Django应用的名称(必须位于INSTALLLED_APPS中)和你想使用的User模型的名称。

(3)在admin文件中设置展示内容

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 ReadOnlyPasswordHashField from repository.models import UserProfile class UserCreationForm(forms.ModelForm):  #创建时显示的表单信息
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) class Meta:
model = UserProfile
fields = ('email', 'name') def clean_password2(self):  #对字段进行验证
# Check that the two password entries match
password1 = 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 password2 def save(self, commit=True):  
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user class UserChangeForm(forms.ModelForm):  #修改时显示的表单信息
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()  #密码字段显示时是hash加密只读字段 class Meta:
model = UserProfile
fields = ('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 value
return self.initial["password"] class UserProfileAdmin(BaseUserAdmin):  #用于注册的表类
# The forms to add and change user instances
form = UserChangeForm
add_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_active','is_staff','is_superuser','role','user_permissions','groups',)}),
)
# 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',) # Now register the new UserAdmin...
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)

二:通用权限框架设计

(一)业务场景分析(如何去实现将不同权限分配给用户)

python---CRM用户关系管理

(二)权限管理分析

主要实现:将权限列表定义出来,与角色(用户组)相互关联就可以

权限列表实现:

(三)实现方法

(1)定义权限列表文件,将权限列表定义。设置为装饰器,根据每个用户访问的url去反解,获取到对应的权限列表名,从而去数据库中获取,使用has_prem获取是否拥有权限。从而在用户访问url时进行判断

permission_list.py(这部分最好是放入数据库中,可以改进

from kingadmin import permission_hook

perm_dict = {
'repository_table_obj_list':['table_obj_list',"GET",[],{},permission_hook.view_my_own_customers],  
#第一个是url_name,第二个是访问方式,第三个是访问参数必须有的字段,第四个是字段中必须是指定的值,第五个是钩子函数,是对第三,第四参数的补充,实现动态验证
'repository_table_obj_change_view':['table_obj_change',"GET",[],{}],
'repository_table_obj_change': ['table_obj_change', "POST", [], {}],
'repository_table_obj_add_view': ['table_obj_add', "GET", [], {}],
'repository_table_obj_add': ['table_obj_add', "POST", [], {}],
'repository_table_obj_delete_view': ['table_obj_delete', "GET", [], {}],
'repository_table_obj_delete': ['table_obj_delete', "POST", [], {}],
}
from django.conf.urls import url
from kingadmin import views urlpatterns = [
url(r"^login.html$",views.acc_login),
url(r"^logout.html$", views.acc_logout,name="logout"),
url(r"^$",views.app_index),
url(r"^(\w+)/(\w+)/$",views.table_obj_list,name="table_obj_list"),
url(r"^(\w+)/(\w+)/(\d+)/change/$", views.table_obj_change, name="table_obj_change"),
url(r"^(\w+)/(\w+)/add/$", views.table_obj_add, name="table_obj_add"),
url(r"^(\w+)/(\w+)/(\d+)/delete/$", views.table_obj_delete, name="table_obj_delete"),
]

urls文件,可以知道对应的url_name

resolve方法可以翻转获取url的数据

(2)permission文件,用于生成装饰器,验证权限列表

from .permission_list import perm_dict
from django.conf import settings
from django.core.urlresolvers import resolve
from django.shortcuts import render,redirect,HttpResponse

#对权限进行检测
def perm_check(*args,**kwargs):
request = args[]
resolve_url_obj = resolve(request.path)  #1,获取当前请求的url
current_url_name = resolve_url_obj.url_name  #2,把url解析成url_name
match_results = [None,]
match_key = None
if request.user.is_authenticated() is False:   #3,进行用户登录验证
return redirect(settings.LOGIN_URL) for permssion_key,permssion_val in perm_dict.items():
#从权限列表中获取url信息,以及钩子函数(重点)
per_url_name = permssion_val[]
per_method = permssion_val[]
per_args = permssion_val[]
per_kargs = permssion_val[]
per_hook_name = permssion_val[] if len(permssion_val) > else None if per_url_name == current_url_name: #4.匹配url_name
if per_method == request.method: #5.匹配访问方法
args_matched = False #用于匹配参数args,一次参数失败,则失败
request_method_dict = getattr(request, per_method)
for item in per_args:  #6.匹配参数
if request_method_dict.get(item,None):
args_matched = True
else:
args_matched = False
break #一次匹配不上,就跳出
else: #当不存在参数,列表为空时
args_matched = True kwargs_matched = False #用于匹配特定的参数
for k,v in per_kargs.items():  #7.匹配指定参数值
arg_val = request_method_dict.get(k,None)
if arg_val == str(v):
kwargs_matched = True
else:
kwargs_matched = False
else:
kwargs_matched = True hook_matched = False
if per_hook_name:  #8.匹配钩子函数
hook_matched = per_hook_name(request)
else:
hook_matched = True match_results = [args_matched,kwargs_matched,hook_matched] if all(match_results): #9.都匹配了  全局验证,获取了权限名,用于下面数据库查询
match_key = permssion_key
break if match_key:
app_name,*per_name = match_key.split("_")
perm_obj = "%s.%s"%(app_name,match_key)
if request.user.has_perm(perm_obj):  #10.数据库查看用户是否被分配该权限
print("当前用户有权限")
return True
else:
print("当前用户没有权限")
return False
else:
print("未匹配到权限项,当前用户没有权限")
return False

#装饰器函数
def check_permission(func):
def inner(*args,**kwargs):
if not perm_check(*args,**kwargs):
request = args[]
return render(request,"kingadmin/page_403.html")
return func(*args,**kwargs)
return inner

总结:

def perm_check(*args,**kwargs):
.获取当前请求的url,使用resolve解析获取url_name
.匹配用户是否登录,使用user.is_authenticated方法
.使用url_name去权限列表permission_list文件中的权限列表中去匹配权限项
.将权限项解析分为,per_url_name(权限url_name),per_method (url访问方法),per_args (获取的参数名),per_kargs (获取的参数值,字典),per_hook_name (获取的权限钩子函数)
.验证了上面的几部分,获取了权限名,然后去数据库中获取当前用户是否拥有该权限,使用user.has_perm(权限名<注意:权限名是由数据表应用加上权限名>)

(3)钩子函数案例(使当前用户只能访问自己的客户)

def view_my_own_customers(request):
if str(request.user.id) == request.GET.get('consultant'):
return True
else:
return False

python---django中权限框架设计的更多相关文章

  1. python django中restful框架的使用

    在使用django进行前后台分离开发时通常会搭配django-rest-framework框架创建RESTful风格的接口API.框架介绍及版本要求可参考官方地址:https://www.django ...

  2. 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用

    写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...

  3. Python Django中QQ邮箱授权码问题

    Python Django中QQ邮箱授权码问题 系统及软件版本如下: Ubuntu Kylin 16.04 Python 3.5.1 Django 1.9.7 PyCharm Community Ed ...

  4. RSA算法在Python Django中的简单应用

    说明 RSA算法是当今使用最广泛,安全度最高的加密算法. • RSA算法的安全性理论基础 [引]根据百科介绍,对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难, ...

  5. Django万能权限框架组件

    业务场景分析 假设我们在开发一个培训机构的 客户关系管理系统,系统分客户管理.学员管理.教学管理3个大模块,每个模块大体功能如下 客户管理 销售人员可以录入客户信息,对客户进行跟踪,为客户办理报名手续 ...

  6. 测试开发之Django——No4.Django中前端框架的配置与添加

    我们在开发一个web项目的时候,虽然我们不是专业开发,但是我们也想要做出来一个美美的前端页面. 这种时候,百度上铺天盖地的前端框架就是我们的最好选择了. 当然,在网上直接下载的框架,我们是不能直接用的 ...

  7. Python Django 中的STATIC_URL 设置和使用解析

    使用Django静态设置时,遇到很多问题,经过艰苦的Baidu, stack overflow, Django原档阅读,终于把静态图片给搞出来了.特记录下来. 关键的概念:Django中,静态资源的存 ...

  8. python Django中的cookie和session

    目录 Cookie 1.1获取Cookie 1.2设置Cookie Session 1.数据库Session 2.缓存Session 3.文件Session 4.缓存+数据库Session Cooki ...

  9. python框架Django中MTV框架之VIew(业务控制器)

    MTV框架之VIew(业务控制器) 关注公众号"轻松学编程"了解更多. 1.什么是视图 视图层=路由表(urls.py)+视图函数(views.py) 其角色相当于MVC中的Con ...

随机推荐

  1. 使用sqlyog创建数据库的错误

    1.错误代码: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL s ...

  2. 第二阶段每日站立会议Forth Day

    昨天对于程序中的字体显示进行细化修改,使界面更美观 今天准备继续调试手机界面 遇到的问题:上几次Tomcat运行正常,今天突然出现问题,Tomcat服务可以打开,但是无法连接到数据库

  3. Scapy 网段中ping扫描

    安装scapy pip3 install scapy-python3 交互式ip包构造 #scapy >>> ping = sr(IP(dst='202.100.1.1')/ICMP ...

  4. 2018软工实践—Beta冲刺(1)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Beta 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调组内工作 调试服务器性能 展示GitHub当日代码/文档签入记录(组内 ...

  5. 项目Beta冲刺(团队)随笔集

    凡事预则立 项目Beta冲刺准备 第一天 项目Beta冲刺(团队)第一天 第二天 项目Beta冲刺(团队)第二天 第三天 项目Beta冲刺(团队)第三天 第四天 项目Beta冲刺(团队)第四天 第五天 ...

  6. Codeforces Round #105 (Div. 2) D. Bag of mice 概率dp

    题目链接: http://codeforces.com/problemset/problem/148/D D. Bag of mice time limit per test2 secondsmemo ...

  7. AT89C51的内部4K flash,

    AT89C51的内部4K flash, 是用来下载程序代码的,程序运行时只能做读取数据操作,不能写入.单片机断电时需要候保存数据,可以选择 带EEPROM的单片机 就可以,如STC 系列的单片机有内部 ...

  8. loadrunner汉化【运行时设置】菜单选项截图

                                 来自为知笔记(Wiz)

  9. dotnet core sdk 2.1 在centos下的安装

    1. 安装微软的仓库 rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm 2. 修改仓库 ...

  10. git bash使用(markdown版)

    前言 我是通过这个来学习的.个人愚笨,琢磨了半天,终于搞通了,醉了醉了,以前一直使用svn,用git确实有点水土不服.本文以如何使用git为主来展开,不涉及太多理论. git是分布式的版本管理.什么叫 ...