Django之权限(起步)
一. 权限概述
1. 认识权限
为什么要有权限? 因为权限让不同的用户拥有不同的功能. 权限可以对功能进行划分.
生活中处处有权限. 比如, 腾讯视频会员才有观看某个最新电影的权限, 你有房间钥匙就有了进入这个房间的权限. 同样, 程序开发过程中也有权限, 我们今天所说的权限指的是web网站权限, 对于不同用户访问web服务时应该有不同的功能. 例如: 一个公司有CEO, 销售主管, 销售等等, 不同的用户能访问的服务也不是完全相同的. 处于这样的需求下, 我们就需要权限控制了.
2. 为什么要开发权限组件?
组件可以减少代码的重复, 能提高我们的开发效率--开发一次组件, 那么在以后的项目中可以一直使用.
3. web开发中权限是指什么?
首先我们要认识到, web程序是通过 url 的切换来查看不同的页面(功能)的, 所以权限指的其实就是一个含有正则表达式的URL, 对url控制就是对权限的控制.
结论: 一个人有多少权限就取决于他有多少个URL的访问权限.
二. 权限表结构设计
1.版本一
按照生活中的实际情况来看, 一个用户有多个权限, 一个权限也可以分配给多个用户, 所以我们可以设计出下面的三张表:
分析: 设计完该表结构之后, 我们又考虑到这种情况: 如果我们再新增10个用户, 每个用户都有权限表中的2个权限, 这意味着我们就要在"权限和用户关联表"中新增40条记录. 如果再拓展到我们的实际生活中, 又会出现怎样的情况呢? 生活中一个web网站肯定不止2个url, 这就意味着每新增一个客户, 我们就要在某些表中增加若干条记录. 这样做不仅加重的程序员工作任务, 而且造成了数据库空间的严重浪费. 很显然, 此表有待改进!
2. 版本二
观察生活中的实际情况, 我们发现, 某些网站有普通用户和VIP用户, 部分网站的VIP用户也分了等级. 此时我们思考: 这样的做法实际上是给用户分了类, 把我们的用户分为了不同的角色. 是的, 此时我们再进一步联想: 我们是否也可以对用户进行角色划分, 然后再对不同的角色进行权限的分配呢?
- 分析:
- 一个人可以有多个角色
- 一个角色可以有多个人
- 一个角色可以有多个权限
- 一个权限可以分配给多个角色
以下是我们的表结构设计:
调整以后的表结构, 由原来的基于用户的权限控制转换成基于角色的权限控制(RBAC), 以后再进行权限分配时只需要给指定角色分配一次权限, 给众多用户分配指定角色即可.
三. Django项目中进行权限设置
步骤概述:
- 1.数据库配置(使用Django自带数据库即可)
- 2.models.py文件: 创建三张表, 分别是用户表, 角色表, 权限表
- 3.使用Django自带的admin来对各个表进行数据添加
- 4.路由匹配(urls.py文件)
- 5.视图函数(views.py文件)
- 6.自定义中间件
Django生命周期的回顾
在进行Django权限设置之前, 我们首先要回顾一下Django的生命周期:
1. models.py文件配置
- 创建项目
MyLuffyPermission
, app名称为rbac
. rbac/models.py
: 我们进行权限表结构设计时, 共有5张表, 其中2张是关系表, 所以models.py文件中只有3个model, 分别是权限表, 角色表和用户表.- 数据库迁移指令
python manage.py makemigrations
python manage.py migrate
2. 使用Django自带的admin对表进行数据添加
(1) 创建超级用户
(2) 对rabc/admin.py
文件进行配置
from django.contrib import admin
from rbac import models
class PermissionModelAdmin(admin.ModelAdmin):
list_display = ['title', 'url'] # 展示的字段
list_editable = ['url'] # 编辑的字段
admin.site.register(models.Permission, PermissionModelAdmin)
admin.site.register(models.Role)
admin.site.register(models.User)
(3)启动Django项目, 浏览器输入127.0.0.1:8000/admin/
, 回车. 对数据库进行相关信息的添加与修改.
3. rbac组件的开发
在rabc应用中创建一个middlewares的文件夹, 在该文件夹中新建rabc.py
, 它就是我们自定义的一个中间件, 作用是权限校验.
rabc/middlewares/rabc.py
: 该中间件的编写分三步走:- (1)获取当前访问的url
- (2)获取当前用户权限信息
- (3)权限校验
- 具体代码如下所示:
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse
import re
class RabcMiddleware(MiddlewareMixin):
def process_request(self, request):
# 1.获取当前访问的URL
url = request.path_info
print(111111)
# 如果当前的url是白名单中的内容,return None,即允许该url通过校验
for i in settings.WHITE_LIST:
if re.match(i, url): # 如果匹配成功
return # 通过校验
# 2.获取当前用户的权限信息 注意session中的键值对是在登录的时候(web/views/account)设置的
permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
print(222222)
# 3.权限的校验
for i in permission_list:
# URL权限 匹配成功
if re.match(r"^{}$".format(i['permissions__url']), url):
print(333333)
return
# 校验失败,拒绝访问
return HttpResponse('没有访问权限')
4. 路由匹配, 视图函数
(1) MyluffyPermission/urls.py
(2) 创建一个名叫web
的app应用, 并在该应用中创建urls.py
文件
# 创建app
python manage.py startapp app的名称
# 注册app
找到MyluffyPermission/settings.py文件下的INSTALLED_APPS项,然后注册app
(3) 在web/urls.py文件中写我们的路由匹配
(4) 在web应用下创建一个名为views
的python包
, 对视图函数进行分类, 每个角色的功能单独用一个.py
文件来写.
5. 登录功能
在成功配置完我们的rbac组件之后(主要包括rbac/middlewares/rbac.py
和rbac/migrations/middles.py
), 我们现在开始进行对登录功能的编写.
(1)路由匹配: web/urls.py
from django.conf.urls import url
from web.views import account
urlpatterns = [
# 用户登录
url(r'^login/$', account.login, name='login'),
]
(2)视图函数: web/views/account.py
from django.shortcuts import HttpResponse, redirect, render, reverse
from rbac import models
from django.conf import settings
def login(request):
if request.method == 'POST':
# 获取提交的数据
user = request.POST.get('user')
pwd = request.POST.get('pwd')
# 数据库匹配管理对象
obj = models.User.objects.filter(name=user, password=pwd).first()
if not obj: # 错误优先
return render(request, 'login.html', {'error_msg': '用户名或密码错误'})
# 登录成功,保存用户权限信息:
ret = obj.roles.all().filter(permissions__url__isnull=False).values(
'permissions__url',
'permissions__title',).distinct()
request.session[settings.PERMISSION_SESSION_KEY] = list(ret)
return HttpResponse("登录成功")
return render(request, 'login.html')
对account.py
文件中其中两行代码的解释:
ret = obj.roles.all().filter(permissions__url__isnull=False).values(
'permissions__url',
'permissions__title',).distinct()
"""
obj -- User对象
.roles.all() -- 通过User对象拿到该用户的所有角色对象(roles)
.filter(permissions__url__isnull=False)
-- permissions__url ==> 角色对象(roles)跨表查询Permission表的 URL权限(url)信息
-- isnull=False ==> isnull表示空,那么isnull=False表示不为空,也就是说 整个ORM语句筛选出了"URL权限不为空的角色对象"
.values('permissions__url','permissions__title')
-- 拿到角色的 URL权限和权限标题 组成的字典
.distinct() -- 去重
"""
request.session[settings.PERMISSION_SESSION_KEY] = list(ret)
# request.session[key] = value表示设置session数据
# 由ret=xxx.values(xxx)可知:ret是一个QuerySet对象.
# 由于request.session设置session时,会把数据转换为json格式,而ret却是一个QuerySet,因此我们把ret转换为列表后,就可以设置session了
# PERMISSION_SESSION_KEY是我们自定义的一个配置信息,我们把它写在settings.py文件里. 配置它的目的是:今后我们再次设置session时,它的key就是一个动态的可变的,如果需要修改key,我们只需要在settings.py文件里重新配置即可,而不再需要找到对应的函数,重复修改.从而达到简化我们代码修改的工作量.
(3)模板文件: web/templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>
用户名:<input type="text" name="user">
</p>
<p>
密码:<input type="password" name="pwd">
</p>
<p style="color: red">{{ error_msg }}</p>
<button>登录</button>
</form>
</body>
</html>
Django之权限(起步)的更多相关文章
- Django万能权限框架组件
业务场景分析 假设我们在开发一个培训机构的 客户关系管理系统,系统分客户管理.学员管理.教学管理3个大模块,每个模块大体功能如下 客户管理 销售人员可以录入客户信息,对客户进行跟踪,为客户办理报名手续 ...
- [Django]用户权限学习系列之权限管理界面实现
本系列前三章: http://www.cnblogs.com/CQ-LQJ/p/5604331.htmlPermission权限基本操作指令 http://www.cnblogs.com/CQ-LQJ ...
- [Django]用户权限学习系列之设计自有权限管理系统设计思路
若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...
- [Django]用户权限学习系列之User权限基本操作指令
针对Django 后台自带的用户管理系统,虽说感觉还可以,但是为了方便用户一些操作,特别设计自定义的用户权限管理系统. 在制作权限页面前,首先需要了解权限和用户配置权限的指令,上章讲到权限的添加,删除 ...
- [Django]用户权限学习系列之Permission权限基本操作指令
若需建立py文件进行测试,则在文件开始加入以下代码即可 #coding:utf-8 import os os.environ.setdefault("DJANGO_SETTINGS_MODU ...
- 【django之权限组件】
一.需求分析 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,一个角色拥有若干权限.这样,就构造成& ...
- django用户权限操作
第一步:创建数据库和超级管理员,为了比较方便使用(里面有些的是没用的),额外新增 chioces , per_method , argument_list # 用户权限# 建立一个权限表,将映射关系存 ...
- Django之权限管理
Django权限管理之初步完整版 项目背景:这是一个权限管理系统(给一些角色和他们的权限指URL和页面可以删除的按钮比如:增删改查) 使用到了中间件,和初始化权限,使用了admin的后台管理系统. 我 ...
- django通用权限控制框架
在web项目中根据不同的用户肯定会限制其不同的权限,利用以下模块可以满足日常几乎所有的权限控制 permission_hook.py # 自定义权限控制,必须返回True/false ,True表 ...
随机推荐
- c++中new的知识点
在练习内存池时,发现需要重载new,可是这个重载只是重载了operator new,那么还有哪几种new呢,下面来记录一下 首先记录一个点,在类中重载operator new,默认就是静态成员函数,所 ...
- unity vulkan snapdragon profiler
your device does not match the hardware requirements of this application 遇到上面那个warning 跟了下 是vulkan c ...
- HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2
/* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...
- MFC 标签页Tab Control
自带的标签页不好用,因此借助了TabSheet文件TabSheet源码 1.在解决方案资源管理器——项目处鼠标右键——在文件资源管理器中打开文件夹(或者按下图,更方便),把TabSheet.h.Tab ...
- 2019CCPC秦皇岛自我反省&部分题解
练了一年半了,第一次打CCPC,险些把队友坑了打铁,最后也是3题危险捡了块铜. 非常水的点双连通,我居然不相信自己去相信板子,唉,结果整来整去,本来半个小时能出的题,整到了3个小时,大失误呀,不然就可 ...
- HDU 4496 D-City —— (并查集的应用)
给出n个点和m条边,一条一条地删除边,问每次删除以后有多少个联通块. 分析:其实就是并查集的应用,只是前一阵子一直做图论思路一直囿于tarjan了..方法就是,记录每一条边,然后从最后一条边开始不断的 ...
- 西湖论剑2019--一道MISC题目的解题思路
TTL题的writeup 第一次打西湖论剑,啥都不懂,被题目虐的很惨,一共就做出来两道题,但也算有收获.这里分享一下TTL那道misc题目的writeup,算是给自己点安慰吧. 题目描述 我们截获了一 ...
- Linux设备驱动程序 之 内核符号表
insmod使用公共内核符号表来解析模块中未定义的符号.功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的.当模块装载到内核后,它所导出的任何符号都会变成内核符号 ...
- rest-assured学习资料
rest-assured 使用指南 https://blog.csdn.net/wx19900503/article/details/54944841/
- LC 873. Length of Longest Fibonacci Subsequence
A sequence X_1, X_2, ..., X_n is fibonacci-like if: n >= 3 X_i + X_{i+1} = X_{i+2} for all i + 2 ...