Django--权限组件
创建组件
需求分析:
创建独立app, rbac
##注意:
app创建后需要注册到setting.py中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rbac.apps.RbacConfig',
'app01.apps.App01Config',
]
设计权限表
方案1:
创建用户表和创建权限表,然后两个表通过一个用户可能有多各权限 然后一个权限可以属于多个用户,所以两张表创建多对多关系,但是存在很多用户有相同的权限字段,所以参考方案二。
方案2:
创建用户表、创建权限表和角色表,为每个角色添加权限,然后用户通过角色获取自己的权限,分析如下所示
用户表:
ID username password ....
番禺
夹缝
果冻
鲁宁 角色表:
ID title
CEO
CTO
COO
部门经理
技术员 用户和角色关系表:
用户ID 角色ID 权限表:
ID url title
/index/ 首页
/userinfo/ 用户列表
/userinfo/add/ 添加用户
/userinfo/del/(\d+)/ 删除用户
/userinfo/edit/(\d+)/ 修改用户 角色权限关系表:
角色ID 权限ID
具体表设计如下所示:
from django.db import models class Permission(models.Model):
"""
权限表
"""
title = models.CharField(verbose_name='标题',max_length=)
url = models.CharField(verbose_name="含正则URL",max_length=)
is_menu = models.BooleanField(verbose_name="是否是菜单") class Meta:
verbose_name_plural = "权限表" def __str__(self):
return self.title class User(models.Model):
"""
用户表
"""
username = models.CharField(verbose_name='用户名',max_length=)
password = models.CharField(verbose_name='密码',max_length=)
email = models.CharField(verbose_name='邮箱',max_length=) roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
class Meta:
verbose_name_plural = "用户表" def __str__(self):
return self.username class Role(models.Model):
"""
角色表
"""
title = models.CharField(max_length=)
permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
class Meta:
verbose_name_plural = "角色表" def __str__(self):
return self.title
然后通过管理类同步数据库,添加数据。
. 权限录入:
CEO:番禺
/userinfo/
/userinfo/add/
/userinfo/edit/(\d+)/
/userinfo/del/(\d+)/
/order/
/order/add/
/order/edit/(\d+)/
/order/del/(\d+)/
总监:鲁宁
/userinfo/
/userinfo/add/
/order/
/order/add/
经理:肾松
/userinfo/
/order/
业务员:肾松,文飞,成栋
/order/
配置用户调用接口
1. 本地化用户权限
在rbac中创建一个初始化文件,用于本地化权限信息,使调用者方便调用
from django.conf import settings def init_permission(request,user):
"""
本地化用户权限"""
# 获取当前用户所有权限(重)
permission_list = user.roles.values('permissions__url').distinct()
request.session[settings.PERMISSION_LIST] = [url['permissions__url'] for url in permission_list]
2. 通过中间键进行用户请求url过滤
settings.py中
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'rbac.middleware.PermissionMiddleware', # 将添加的中间件配置到settings中
]
#####################confirm###################
SESSION_KEY = 'auth_user'
PERMISSION_LIST = 'permission_list' INVALIDATION_LIST = [
'/admin.*',
'/login/',
'/register/',
]
创建middleware.py
# encoding:utf-8
# Author:"richie"
# Date:11/7/2017
import re
from django.conf import settings
from django.shortcuts import HttpResponse,redirect
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response class PermissionMiddleware(MiddlewareMixin): def process_request(self, request): current_path = request.path_info for url in settings.INVALIDATION_LIST:
if re.match(url,current_path):
return None permission_list = request.session.get(settings.PERMISSION_LIST) if not permission_list:
return redirect('/login/') flag = False for url in permission_list:
regular = "^{0}$".format(url) # 因为添加url的时候没有添加严格匹配的规则,所以在这里转格式
if re.match(regular,current_path):
flag = True
break if not flag:
# 没有匹配上
return HttpResponse('无权访问')
权限组件使用
分配url,
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^login/', views.login, name='login'),
url(r'^index/', views.home, name='home'),
url(r'^userinfo/', views.home, name='home'),
url(r'^userinfo/add', views.home, name='home'),
url(r'^order/', views.home, name='home'),
url(r'^order/add', views.home, name='home'),
]
定义视图函数:
from django.shortcuts import render,redirect
from django.conf import settings
from rbac.models import User
from rbac.service import init_permission
# Create your views here. class UserLoginForm(forms.ModelForm):
"""
定义用户登录的from表单
"""
class Meta:
model = models.User
fields = ['username','password'] def login(request):
if request.method == 'POST':
# 获取用户from表单数据
login_form = forms.UserLoginForm(request.POST)
# 数据格式验证
if login_form.is_valid():
#用户认证
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
# 用户数据数据库验证
user =User.objects.filter(username=username,password=password).first()
if user:
#初始化权限系统
init_permission(request,user)
# 添加用户信息
request.session[settings.SESSION_KEY] = {'uid':user.id,'username':username}
return redirect('/home/')
else:
# 登录失败 添加错误信息
login_form.errors.update({'user_error': '用户名或密码错误'})
else:
login_form = forms.UserLoginForm() return render(request, 'login.html',{'form':login_form}) def home(request):
"""
主页面
:param request:
:return:
""" #获取用户名信息
username = request.session.get(settings.SESSION_KEY).get('username')
return render(request,'home.html',locals())
3. 定义模板页面
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body> <form method="post" novalidate>{% csrf_token %}
{{ form.errors.user_error }}
{% for filed in form %}
<p>{{ filed.label_tag }}{{ filed }}</p>
<p>{{ filed.errors.as_text }}</p>
{% endfor %} <input type="submit" value="提交">
</form> </body>
</html>
定义home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
{{ username }}
</body>
</html>
Django--权限组件的更多相关文章
- Django的rest_framework的权限组件和频率组件源码分析
前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...
- Django - 权限分配、权限组件与CRM整合
一.权限分配 需求:为用户分配角色,为角色分配权限,如下图效果: 1.视图代码: from django.shortcuts import render from django.http import ...
- Django REST framework —— 权限组件源码分析
在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...
- Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)
一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...
- $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete
一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...
- Django高级篇三。restful的解析器,认证组件,权限组件
一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...
- 巨蟒django之权限10,内容梳理&&权限组件应用
1.CRM项目内容梳理: 2.权限分配 3.权限组件的应用
- Django day27 认证组件,权限组件()
一:认证组件 1.写一个类 class LoginAuth(): # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象 def authenticate(sel ...
- Django框架之DRF 认证组件源码分析、权限组件源码分析、频率组件源码分析
认证组件 权限组件 频率组件
- DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件 本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...
随机推荐
- 前端笔记——如何控制表单控件中的disabled
0.前言 本文主要说明如何使能或禁止表单控件.表单控件具有disabled属性,通过设置该属性可以禁止所有的input控件,input的更多属性请参考资料[1].下面就通过一个简单的例子说明如 ...
- vue路由
vue-router 现在的应用都流行SPA应用(single page application) 传统的项目大多使用多页面结构,需要切换内容的时候我们往往会进行单个html文件的跳转,这个时候受网络 ...
- python运算符优先级问题
附上 对于or与and运算 其一, 在不加括号时候, and优先级大于or 其二, x or y 的值只可能是x或y. x为真就是x, x为假就是y 第三, x and y 的值只可能是x或y. x为 ...
- 使用Flink时从Kafka中读取Array[Byte]类型的Schema
使用Flink时,如果从Kafka中读取输入流,默认提供的是String类型的Schema: val myConsumer = new FlinkKafkaConsumer08[String](&qu ...
- Influxdb1.2.2安装
一.文件准备 1.1 文件名称 influxdb-1.2.2.x86_64.rpm 1.2 下载地址 https://portal.influxdata.com/downloads [注意.注意.注意 ...
- for in,Object.keys()与for of的区别
for in 1.for in一般用于遍历对象的属性: 2.作用于数组的for in除了会遍历数组元素外,还会遍历自定义可枚举的属性,以及原型链上可枚举的属性:3.作用于数组的for in的遍历结果是 ...
- 给虚拟机添加新硬盘并分区,fdisk查看分区,分区,重新读取分区表信息partprobe,格式化,挂载,查看分区挂载信息,自动挂载文件/etc/fstab,/etc/fstab文件错误导致重启崩溃后的修复
1.虚拟机关机断电 2.添加硬盘 2.开机 3.fdisk -l查看刚才新添加的硬盘 [root@localhost ~]# fdisk -l 磁盘 /dev/sda:21.5 GB, 2147483 ...
- 【java】文件操作java.io.File
package 文件操作; import java.io.File; import java.io.IOException; public class TestFile { public static ...
- go实例之排序
1.默认排序 使用sort包进行排序.排序是就地排序,因此它会更改给定的切片,并且不返回新的切片. package main import "fmt" import "s ...
- webpack 3.X学习之多页面打包
简介 我们开发不可能只写一个页面,每次都要写很多页面,这时为了开发效率,我们使用前端自动化工具webpack,那么webpack是如何打包页面的呢?又是如何打包多页面的呢? 单页面打包 我们知道要打包 ...