权限管理之用户登记录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

 

posted on 2018-03-29 11:44  王大拿  阅读(189)  评论(0)    收藏  举报

导航