一. 权限概述

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. c++中new的知识点

    在练习内存池时,发现需要重载new,可是这个重载只是重载了operator new,那么还有哪几种new呢,下面来记录一下 首先记录一个点,在类中重载operator new,默认就是静态成员函数,所 ...

  2. unity vulkan snapdragon profiler

    your device does not match the hardware requirements of this application 遇到上面那个warning 跟了下 是vulkan c ...

  3. 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 题意: ...

  4. MFC 标签页Tab Control

    自带的标签页不好用,因此借助了TabSheet文件TabSheet源码 1.在解决方案资源管理器——项目处鼠标右键——在文件资源管理器中打开文件夹(或者按下图,更方便),把TabSheet.h.Tab ...

  5. 2019CCPC秦皇岛自我反省&部分题解

    练了一年半了,第一次打CCPC,险些把队友坑了打铁,最后也是3题危险捡了块铜. 非常水的点双连通,我居然不相信自己去相信板子,唉,结果整来整去,本来半个小时能出的题,整到了3个小时,大失误呀,不然就可 ...

  6. HDU 4496 D-City —— (并查集的应用)

    给出n个点和m条边,一条一条地删除边,问每次删除以后有多少个联通块. 分析:其实就是并查集的应用,只是前一阵子一直做图论思路一直囿于tarjan了..方法就是,记录每一条边,然后从最后一条边开始不断的 ...

  7. 西湖论剑2019--一道MISC题目的解题思路

    TTL题的writeup 第一次打西湖论剑,啥都不懂,被题目虐的很惨,一共就做出来两道题,但也算有收获.这里分享一下TTL那道misc题目的writeup,算是给自己点安慰吧. 题目描述 我们截获了一 ...

  8. Linux设备驱动程序 之 内核符号表

    insmod使用公共内核符号表来解析模块中未定义的符号.功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的.当模块装载到内核后,它所导出的任何符号都会变成内核符号 ...

  9. rest-assured学习资料

    rest-assured 使用指南 https://blog.csdn.net/wx19900503/article/details/54944841/

  10. 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 ...