权限管理之用户登记录session信息,中间件,自定义tag,和一些其他操作
1.在对不同的用不分配好不同的角色之后,当用户登录之后,根据用户的用 户名----->角色--------->权限
在数据库中找到用户的权限信息,
具体操作如下
用户登录,走这个视图函数
def login(request): if request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') #获取用户输入的用户名和密码, #取数据库中看是否数据是对的 ret=UserInfo.objects.filter(name=user,pwd=pwd) #当数据是对的,将用户的ID写入session信息中去 if ret: #将ID写入session 是因为每个用户的id都不同的 request.session['user'] = ret[0].id #调用函数,去权限表中将用户的权限信息取出,() #主要是去取出用户可登录的url 将取到的数据放到session中, # 在中间件中去取出,用户判断用户是否有权限登录这个url
#将session中写如权限表单和,写入网页信息的功能封装在一个函数中,实现功能的解耦,在这里调用函数来写session
from rbac.server.initial import initial_session initial_session(request,user) return HttpResponse('OK') else: return redirect('/login/') return render(request,'login.html')
initial_session.py 代码如下
def initial_session(request,user): # 方式1: # permission_info = user.roles.all().values("permissions__url", "permissions__title").distinct() # temp = [] # for i in permission_info: # temp.append(i["permissions__url"]) # request.session["permission_list"] = temp # ["url","url1",.....] # 方式2: # 创建一个数据格式: 包含所有权限url,权限所在组,权限的编号 permission_info = user.roles.all().values("permissions__id", "permissions__url", "permissions__title", "permissions__permission_group_id", "permissions__code", "permissions__parent_id", "permissions__permission_group__menu__caption", "permissions__permission_group__menu_id", ).distinct() print("permission_info",permission_info) # 创建生成菜单的数据 permission_list=[] # permission_info=[{"permissions__url":"",permissions__title:""},{}] for permission_item in permission_info: temp={ "id":permission_item["permissions__id"], "url":permission_item["permissions__url"], "title":permission_item["permissions__title"], "pid":permission_item["permissions__parent_id"], "menu_name":permission_item["permissions__permission_group__menu__caption"], "menu_id":permission_item["permissions__permission_group__menu_id"], } permission_list.append(temp) #这个内容会在后边的视图函数中用到,并对数据进行整理成字典的形式,能够依据字典的active的值来判断是否展开,收起 request.session["permission_list"]=permission_list # 将登录用户所有权限信息写入到session中 permission_dict = {} for item in permission_info: gid = item["permissions__permission_group_id"] if gid in permission_dict: permission_dict[gid]["urls"].append(item["permissions__url"]), permission_dict[gid]["codes"].append(item["permissions__code"]), else: permission_dict[gid] = { "urls": [item["permissions__url"], ], "codes": [item["permissions__code"]] }
#这个保存在session中的permission_dict会在后边的权限中间件中中进行验证用户是否有此url等登陆权限 request.session["permission_dict"]=permission_dict '''
数据转换分析::::::
元数据: 保存在permission_list中的信息 permission_list=[ {"permissions__url":"/orders/","permissions__group_id":"2","permissions__code":"list"}, ] 转换数据: 这是转换后保存在session中的permission_dict 信息 permission_dict = { 2: { "urls": ["/orders/","/orders/add","/orders/delete/(\d+)",], "codes": ["list","add","delete",] }, 1: { "urls": ["/users/","xxx" ], "codes": ["list","xxx" ] }, } ''' 列子:egon登陆成功之后他session中的字典是这样的 ''' egon: permission_dict={ 2:{ "urls":["orders",], "codes:["list",] } } #alex登陆成功之后的字典是这样的 alex: permission_dict= { 1:{ "urls":["/users/"], "codes":["list"] }, 2:{ "urls":["/orders/","/orders/add"], "codes":["list","add"] } } request.session["permission_dict"]=permission_dict
在中间键中取出响应的session值,进行判断,然后再进行处理
#encoding=utf-8 from django.shortcuts import redirect,render,HttpResponse from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self,request): #第一步,先将登录注册页面写成白名单的形式 bai_List=['/login/','/regester/','/$','/admin/.*'] #取出用户登陆的地址 url=request.get_full_path() print('这是登录用户输入的url',url) import re #用正则匹配用户输入的地址是否是白名单中的地址 for i in bai_List: ret=re.match(i,url) #是的话, if ret: # print('得到数据了') #直接进入相关的网页 return None # print('111') #如果地址不是白名单中的地址的话走这里 #从session中取出user,如果有的话,证明用户已经登录了 user=request.session.get('user') #如果取不出user值的话表示用户还没有登录 if not user: #让用户去登录 return redirect('/login/') #已经登录的话走这里 permission_dict=request.session.get('permission_dict') #取出权限表单中的信息,表单形式如上边的代码所示 #通过看形式可以知道实际要的信息是值,用如下方式取出 for permission in permission_dict.values(): #这里里边放的是url组成的列表 regs=permission['permissions__url'] #这里边写的是code 信息组成的列表 #注意 code信息是用来返回到页面, # 依据里边是否有删除和编辑来判断是否要显示编辑删除等按钮 codes=permission['permissions__code'] #循环regs中的url for reg in regs: #用字符串拼接的方法将数据拼接成如 '/users/delete/(\d+)$'的这种形式, # 用于当作正则匹配的规则 perurl='%s$'%(reg) #匹配用户登录的URL地址 ret2=re.match(perurl,url) if ret2: # 这里request相当于实例化一个对象,然后直接给这个实例化的对象一个静态属性, # 利用request这个对象可以在。全局中使用的特点来去view视图中调用。 #匹配成功,将codes的信息放进去, request.codes=codes return None return HttpResponse('没有权限') def process_response(self,request,response): return response
问题:我每次访问一个页面如(users/ orders)都要重新取出session中的信息构建成带有active的字典这样太麻烦
在templatetages中定义一个自己写的筛选器,这样访问不同的类型都会能够渲染出左侧菜单
#写一个函数是inclusion_tag 类的用于取出session中的信息,在html页面中调用此方法 渲染出左侧菜单, from django import template register=template.Library() @register.simple_tag def mul(x,y): return x*y @register.inclusion_tag("menu.html") def get_menu(request):
#在这里用到的是保存在session中的permission_list permission_list = request.session["permission_list"] #############temp_dict:存储所有放到菜单栏中的权限 temp_dict = {} for item in permission_list: pid = item["pid"] if not pid: item["active"] = False temp_dict[item["id"]] = item # print(temp_dict) #######将需要标中的active设置True current_path = request.path_info import re for item in permission_list: pid = item["pid"] url = "^%s$" % item["url"] if re.match(url, current_path): if pid: temp_dict[pid]["active"] = True else: item["active"] = True ########将temp_dict转换为最终的menu_dict的数据格式 menu_dict = {} for item in temp_dict.values(): if item["menu_id"] in menu_dict: temp = {"title": item["title"], "url": item["url"], "active": item["active"]}, menu_dict[item["menu_id"]]["children"].append(temp) if item["active"]: menu_dict[item["menu_id"]]["active"] = True else: menu_dict[item["menu_id"]] = { "title": item["menu_name"], "active": item["active"], "children": [ {"title": item["title"], "url": item["url"], "active": item["active"]}, ] } print(menu_dict)
'''
将permission_info---->
menu_dict = {
1: {
"title": "菜单一",
"active": False,
"children": [
{"title": "添加用户", "url": "xxxxxxxxxxx", "active": False},
{"title": "查看用户", "url": "xxxxxxxxxxx", "active": False},
]},
2: {
"title": "菜单二",
"active": True,
"children": [
{"title": "添加用户", "url": "xxxxxxxxxxx", "active": False},
{"title": "查看用户", "url": "xxxxxxxxxxx", "active": True},
]
}}
'''
return {"menu_dict":menu_dict} 将内容传给menu
menu.html
<div class="menu_list"> {% for item in menu_dict.values %} <div class="item"> <div class="title"><a href="">{{ item.title }}</a></div> {% if item.active %} <div class="con"> {% else %} <div class="con hide"> {% endif %} {% for son in item.children %} {% if son.active %} <p><a href="{{ son.url }}" class="active">{{ son.title }}</a></p> {% else %} <p><a href="{{ son.url }}">{{ son.title }}</a></p> {% endif %} {% endfor %} </div> </div> {% endfor %} </div>
#这个类是用于服务前端的,取出request.code 中的内容,
#实例化permissions类的对象,用于服务前端
class Permissions(object): def __init__(self,code_list): self.code_list=code_list def list(self): return "list" in self.code_list def add(self): return "add" in self.code_list def delete(self): return "delete" in self.code_list def edit(self): return "edit" in self.code_list
浙公网安备 33010602011771号