创建组件

需求分析:

创建独立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--权限组件的更多相关文章

  1. Django的rest_framework的权限组件和频率组件源码分析

    前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...

  2. Django - 权限分配、权限组件与CRM整合

    一.权限分配 需求:为用户分配角色,为角色分配权限,如下图效果: 1.视图代码: from django.shortcuts import render from django.http import ...

  3. Django REST framework —— 权限组件源码分析

    在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...

  4. Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)

    一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...

  5. $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete

    一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...

  6. Django高级篇三。restful的解析器,认证组件,权限组件

    一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...

  7. 巨蟒django之权限10,内容梳理&&权限组件应用

    1.CRM项目内容梳理: 2.权限分配 3.权限组件的应用

  8. Django day27 认证组件,权限组件()

    一:认证组件 1.写一个类 class LoginAuth(): # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象 def authenticate(sel ...

  9. Django框架之DRF 认证组件源码分析、权限组件源码分析、频率组件源码分析

    认证组件 权限组件 频率组件

  10. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

随机推荐

  1. class的二般用法

    一般来说,class就是给一堆元素添加样式的,但是还有二般的用法,就是用来作为一个开关,来切换他的子孙元素的样式.举个例子: <ul> <li><span>1< ...

  2. nginx+redis缓存微信的token数据

    上一篇文章我们讲了如何在负载均衡的项目中使用redis来缓存session数据,戳这里. 我们在项目的进展过程中,不仅需要缓存session数据,有时候还需要缓存一些别的数据,比如说,微信的acces ...

  3. Python爬虫(二十四)_selenium案例:执行javascript脚本

    本章叫介绍如何使用selenium在浏览器中使用js脚本,更多内容请参考:Python学习指南 隐藏百度图片 #-*- coding:utf-8 -*- #本篇将模拟执行javascript语句 fr ...

  4. vue从入门到女装:从零开始搭建后台管理系统(一)安装框架

    安装及运行都是基于node的,不会node的可以自行百度,网上教程很多,也不难 项目效果预览: demo1 demo2 源码下载 开始安装框架: vue ==>vue-cli安装   eleme ...

  5. 数据库、ArcCatalog空间数据源正常访问,数据库设置没问题时,ArcEngine连接SDE时报"ORA-12560: TNS: 协议适配器错误"的解决办法;ArcEngine连接SDE总结

    碰到的问题描述: 通过C# 基于ArcEngine写SDE直连的时候测试项目连接属性设置为如下: tPropSet.SetProperty("User", "GISDAT ...

  6. TypeScript学习笔记之接口类型

    TypeScript的接口,个人理解就是一种约束,包括各种类型的契约或者代码定义上的契约.当然,和java中的用法基本一致,接口可以被继承也可以被实现. 定义一个简单的interface interf ...

  7. 4.前端基于react,后端基于.net core2.0的开发之路(4) 前端打包,编译,路由,模型,服务

    1.简要的介绍 学习react,首先学习的就是javascript,然后ES6,接着是jsx,通常来说如果有javascript的基础,上手非常快,但是真正要搭建一个前端工程化项目,还是有很多坑的 搞 ...

  8. Linux:如何进行c++编程

    不适应美帝的饮食,当一只咸鱼在apartment里Coding一波,学习学习如何在Ubuntu实现C++的编程 正文如下: (预备知识) 学习Vim:  http://www.cnblogs.com/ ...

  9. OC学习11——循环引用与@class

    转载自 OC学习篇之---@class关键字的作用以及#include和#import的区别 一.#import和#include的区别 当我们在代码中使用两次#include的时候会报错:因为#in ...

  10. bzoj 3670: [Noi2014]动物园

    Description 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习 ...