一. 权限概述

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应用下创建一个名为viewspython包, 对视图函数进行分类, 每个角色的功能单独用一个.py文件来写.

5. 登录功能

在成功配置完我们的rbac组件之后(主要包括rbac/middlewares/rbac.pyrbac/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之权限(起步)的更多相关文章

  1. Django万能权限框架组件

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

  2. [Django]用户权限学习系列之权限管理界面实现

    本系列前三章: http://www.cnblogs.com/CQ-LQJ/p/5604331.htmlPermission权限基本操作指令 http://www.cnblogs.com/CQ-LQJ ...

  3. [Django]用户权限学习系列之设计自有权限管理系统设计思路

    若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...

  4. [Django]用户权限学习系列之User权限基本操作指令

    针对Django 后台自带的用户管理系统,虽说感觉还可以,但是为了方便用户一些操作,特别设计自定义的用户权限管理系统. 在制作权限页面前,首先需要了解权限和用户配置权限的指令,上章讲到权限的添加,删除 ...

  5. [Django]用户权限学习系列之Permission权限基本操作指令

    若需建立py文件进行测试,则在文件开始加入以下代码即可 #coding:utf-8 import os os.environ.setdefault("DJANGO_SETTINGS_MODU ...

  6. 【django之权限组件】

    一.需求分析 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,一个角色拥有若干权限.这样,就构造成& ...

  7. django用户权限操作

    第一步:创建数据库和超级管理员,为了比较方便使用(里面有些的是没用的),额外新增 chioces , per_method , argument_list # 用户权限# 建立一个权限表,将映射关系存 ...

  8. Django之权限管理

    Django权限管理之初步完整版 项目背景:这是一个权限管理系统(给一些角色和他们的权限指URL和页面可以删除的按钮比如:增删改查) 使用到了中间件,和初始化权限,使用了admin的后台管理系统. 我 ...

  9. django通用权限控制框架

    在web项目中根据不同的用户肯定会限制其不同的权限,利用以下模块可以满足日常几乎所有的权限控制 permission_hook.py  # 自定义权限控制,必须返回True/false  ,True表 ...

随机推荐

  1. python 套接字Socket详解

    socket简介 1. 什么是socket ? socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是: 它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多 ...

  2. Android之Json

    Servlet部分 public class JasonAction extends HttpServlet { private JsonService service; public void do ...

  3. WPF DevExpress ChartControl使用之XYDiagram

    WPF使用Dev和WinForm有许多不同,相对而言,WPF要更简单和炫酷一点,我只做了一点基本的功能,没有仔细的研究,这里只介绍一下WPF Dev ChartControl绘制XYDiagram的基 ...

  4. k8s部署dashboard

    1.首先去github上找到kubernetes 2.然后找到get started 3.复制yaml文件地址,并wget到服务器上并部署即可 PS:本文把自己部署的yaml文件贴出来:recomme ...

  5. list去重的四种方式

    L=[1,2,3,3,5,5,5,8,4,6,9,7,2,'a','s','a','e','s','z'] def DelDupli(L):    L1=[]    for i in L:       ...

  6. HDU 6102 - GCDispower | 2017 Multi-University Training Contest 6

    个人感觉题解的复杂度很玄,参不透,有没有大佬讲解一下- - /* HDU 6102 - GCDispower [ 数论,树状数组] | 2017 Multi-University Training C ...

  7. BOOTING ELOQUENT MODEL TRAITS

    BOOTING ELOQUENT MODEL TRAITS So I've learnt a little Laravel/Eloquent trick today that is very much ...

  8. Spring详解------事务管理

    目录 1.事务介绍 2.事务的四个特性(ACID) 3.Spring 事务管理的核心接口 4. PlatformTransactionManager  事务管理器 5.TransactionStatu ...

  9. (十八)链接数据库,QSqlTableModel

    QMYSQL——mysql QSQLITE——sqlite QOICQ——orcale 所需头文件 .pro增加 sql #include <QSqlDatabase> #include ...

  10. JetBrains IDE 基本快捷键

    转载自:https://nextfe.com/jetbrains-ide-shortcuts/ 一个好的手艺人很熟悉他的工具.软件开发者也不例外.所以,在编程的过程中,值得了解一些键盘快捷键,以免因为 ...