权限管理简介
web领域的权限
eg:
使用账号访问某个资源 有些人可以访问(VIP) 有些人不能访问(普通用户)
ps:在web领域url其实就是权限 权限就是url
"""本质其实就是当用户登录之后 获取该用户的权限 之后每次用户发送网络请求先核对该请求地址是否在用户可以访问的url列表内 如果在则访问不在拒绝"""
权限的设计
'''用户表'''
id name pwd
1 jason 123
2 tony 321
3 kevin 222
'''权限表'''
id permission
1 添加书籍
2 查看书籍
3 编辑书籍
4 删除书籍
'''用户与权限的关系表'''
id user_id permission_id
1 1 1
2 1 2
3 1 3
RBAC
# 基于角色的权限管理
'''用户表'''
id name pwd
1 jason 123
2 tony 321
3 kevin 222
'''角色表'''
id role
1 CEO
2 保安
3 扫地僧
'''权限表'''
id permission url
1 添加书籍 /add/book/
2 查看书籍 /check/book/
3 编辑书籍 /edit/book/
4 删除书籍 /delete/book/
'''用户角色关系表'''
id user_id role_id
1 1 1
2 2 2
'''角色权限关系表'''
id role_id permission_id
1 1 1
2 1 2
3 1 3
4 1 4
"""
提前在角色和权限关系表中绑定好关系 之后又新用户
只有在用户和角色关系表中添加一两条数据即可!!!
"""
权限管理实战
'''url权限也不是固定写死的 可能会含有正则表达式'''
eg:
/edit/book/1/ /edit/book/(\d+)/
/edit/book/?edit_id=1
/edit/book/.*
1.编写登陆功能 获取用户的权限并存储
2.校验每次用户访问的url比对是否含有该权限
自定义中间件
3.有些权限是所有用户都应该具备的
白名单:里面的东西所有人都可以访问
4.有些url是含有正则的 不能简单的使用成员运算来判断
'''
既然是要在用户访问url做校验是否有权限,所以就要用到自定义中间件的知识了
'''
'''mypermission.py'''
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
import re
class Mypermission(MiddlewareMixin):
def process_request(self, request):
# 定义网站白名单
white_url_list = ['/login/', '/register/', '/admin/.*']
# 1.获取当前请求的url
target_url = request.path
# 1.1先校验是否在白名单中,是则直接放行
for url in white_url_list:
re_path = '^%s$' % url # 将白名单里面的url变成正则表达式,去校验用户访问的url
res = re.search(re_path, target_url)
if res:
return
# 2.获取当前用户的权限列表
permission_list = request.session.get('permission_list')
# 3. 判断当前请求url在不在用户可以访问的url列表中
"""也需要改正正则校验方式"""
# if target_url not in permission_list:
# return HttpResponse('不好意思,你没有权限访问')
for permission in permission_list:
re_path = '^%s$' % permission
res = re.search(re_path, target_url)
if res:
return
return HttpResponse('你没有权限访问')
'''views.py'''
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = models.User.objects.filter(name=username,pwd=int(password)).first()
if user_obj:
# 获取当前用户的权限
permission_list = models.User.objects.filter(name=username,pwd=int(password)).values('roles__permissions__url').distinct()
'''由于用户和权限之前是多对多 所以结果集可能会有重复的元素'''
# 存储当前登录用户的权限 便于后续比对
permission_list = [i.get("roles__permissions__url") for i in permission_list]
# print(permission_list)
request.session['permission_list'] = permission_list
return render(request,'login.html')
# settings里面添加自定义中间件
MIDDLEWARE = [
'app01.permissions.mypermission.MyPermission'
]
'''admin.py'''
from app01 import models
admin.site.register(models.User, UserConfig)
admin.site.register(models.Role)
admin.site.register(models.Permission)
'''models.py'''
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.IntegerField()
roles = models.ManyToManyField(to='Role')
def __str__(self):
return self.name
class Role(models.Model):
title = models.CharField(max_length=32)
permissions = models.ManyToManyField(to='Permission')
def __str__(self):
return self.title
class Permission(models.Model):
name = models.CharField(max_length=32, verbose_name='权限名称')
url = models.CharField(max_length=32, verbose_name='权限url')
def __str__(self):
return self.name
admin配置参数
class BookConfig(admin.ModelAdmin):
list_display = ['title', 'price', 'publish_time'] # 控制展示的字段数量
list_display_links = ['price'] # 指定跳转的字段数据
search_fields = ['title', 'price'] # 上方出现一个搜索框 包含+或 查找
# 回想之前讲解的Q查询进阶用法
list_filter = ['publish','authors'] # 筛选功能 一般填写外键字段 普通字段没有实际意义
def patch_init(self,request,queryset):
queryset.update(price = F('price') + 1000)
patch_init.short_description = '价格批量处理'
actions = [patch_init, ] # 自定义queryset的操作函数
admin.site.register(models.Book, BookConfig)