zoukankan      html  css  js  c++  java
  • 根据权限动态生成二级菜单

    数据库models设计:

    from django.db import models
    
    
    """
    一级菜单
    """
    class Menu(models.Model):
        title = models.CharField(max_length=32, unique=True)
        icon = models.CharField(max_length=32, verbose_name="图标", null=True, blank=True)
    
        class Meta:
            verbose_name_plural = "菜单表"
            verbose_name = "菜单表"
    
        def __str__(self):
            return self.title
    
    """
    有关联Menu表的是可以做二级展示菜单的权限
    未关联Menu表的是不展示的权限
    """
    class Permission(models.Model):
        """权限表"""
        titlt = models.CharField(max_length=32, verbose_name="功能")
        url = models.CharField(max_length=32, verbose_name="权限")
        menu = models.ForeignKey(to="Menu", null=True, blank=True)
    
        class Meta:
            verbose_name_plural = "权限表"
            verbose_name = "权限表"
    
        def __str__(self):
            return self.titlt
    
    
    class Role(models.Model):
        """角色表"""
        name = models.CharField(max_length=32, verbose_name="角色名")
        permissions = models.ManyToManyField(to="Permission", verbose_name="角色所拥有的权限")
    
        class Meta:
            verbose_name_plural = "角色表"
            verbose_name = "角色表"
    
        def __str__(self):
            return self.name
    
    
    class User(models.Model):
        """用户表"""
        name = models.CharField(max_length=32, verbose_name="用户名")
        password = models.CharField(max_length=32, verbose_name="密码")
        role = models.ManyToManyField(to="Role", verbose_name="用户拥有的角色")
    
        class Meta:
            verbose_name_plural = "用户表"
            verbose_name = "用户表"
    
        def __str__(self):
            return self.name

    URL:

    url(r'^login/$', views.login),  

    ----------------------------------------------------------------------------

    url判断要执行的函数

    VIew登录函数:

    from django.shortcuts import render, HttpResponse, redirect, reverse
    from rbac import models
    from django.conf import settings
    from rbac.server.init_permission import init_permission
    
    
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            pwd = request.POST.get("pwd")
            user = models.User.objects.filter(name=username, password=pwd).first()
            if not user:
                error_msg = "用户名或密码错误!"
                return render(request, "login.html", {"error_mag": error_msg})
    
            # 调用封装的函数
            init_permission(user, request)
            return redirect(reverse("customer"))
        return render(request, "login.html")

    ------------------------------------------------------------------------------------------------------------

    用户在登录界面输入账号密码之后在login中获取并和数据库中的用户数据进行比对,
    如果取到了真实的用户, 则证明用户输入的账号密码正确, 调用封装好的函数进行设置session, 返回重定向到页面

    封装好的设置session的函数:

    """
    获取权限的函数
    封装成组件
    """
    from django.conf import settings
    
    
    def init_permission(user, request):
        permission_list = user.role.filter(permissions__url__isnull=False).values(
            "permissions__url",
            "permissions__titlt",
            "permissions__menu__title",
            "permissions__menu__id",
            "permissions__menu__icon",
        ).distinct()
        # 存放权限信息的列表
        permission_li = []
        # 存放菜单信息的列表
        menu_li = {}
    # 单级菜单循环 for i in permission_list: # i 为字典形式 permission_li.append({"url": i["permissions__url"]})
    # if i.get("permissions__is_menu"): # menu_li.append({"url": i["permissions__url"], # "icon": i["permissions__icon"], # "titlt": i["permissions__titlt"], # }) # 二级菜单循环 menu_id = i.get("permissions__menu__id") if not menu_id: continue if menu_id not in menu_li: menu_li[menu_id] = { "title": i["permissions__menu__title"], "icon": i["permissions__menu__icon"], "children": [ {"title": i["permissions__titlt"], "url": i["permissions__url"]} ] } else: menu_li[menu_id]["children"].append( {"title": i["permissions__titlt", "url": i["permissions__url"]]} ) # 将权限信息写入session request.session[settings.PERMISSION_SESSION_KEY] = permission_li # 将菜单信息写入session request.session[settings.MENU_SESSION_KEY] = menu_li

    ---------------------------------------------------------------------------------------------------------------------

    在数据库中取出需要的数据并去重,
    二级菜单循环中获取menu_id是要判断Permission表是否有外键关联Menu表(即是否是二级展示的权限url)

    获取session:

    from django import template
    
    register = template.Library()
    
    from django.conf import settings
    import re
    
    """
    在此函数内获取init_permission初始化方法设置的session值
    并且传递个menu.html进行渲染
    """
    @register.inclusion_tag("menu.html")
    def menu(request):
        menu_list = request.session.get(settings.MENU_SESSION_KEY)
    
        return {"menu_list": menu_list}

    动态页面渲染:

    <div class="multi-menu">
        {% for i in menu_list.values %}
            <div class="item">
                <div class="title"> <i class="fa {{ i.icon }}"></i> {{ i.title }}</div>
                <div class="body">
                    {% for f in i.children %}
                        <a href="{{ f.url }}">{{ f.title }}</a>
                    {% endfor %}
                </div>
            </div>
        {% endfor %}
    </div>

    中间件判断权限:

    from django.utils.deprecation import MiddlewareMixin
    from django.conf import settings
    from django.shortcuts import render, HttpResponse, redirect, reverse
    import re
    
    
    class Permissionmiddleware(MiddlewareMixin):
        def process_request(self, request):
            # 目的 : 对权限进行校验
            # 获取当前访问的URL
            url = request.path_info
            # 判断访问的URL是否在白名单中
            for i in settings.WHITE_URL_LIST:
                if re.match(i, url):
                    return
    
            # 获取用户所拥有的权限
            permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
            # 将获取的URL和获取的权限进行一致性校验
            for item in permission_list:
                url_p = item["url"]
                if re.match("^{}$".format(url_p), url):
                    return
            else:
                return HttpResponse("没有权限!")

    --------------------------------------------------------------------------------------------------------

    在web初次发送请求时, 系统会在中间件中判断所请求时用的url是否在设置的白名单中, 如果在正常向下执行, 不在则获取用户的所拥有的权限,
    如果url在设置的白名单内, 执行白名单内的函数, 函数内会设置新的session, 当返回响应重定向时, 再次经过中间件, 则判断用户的权限(session和url的一致性校验)


  • 相关阅读:
    Unity-WIKI 之 AllocationStats(内存分配)
    Unity-WIKI 之 DebugLine
    Unity-WIKI 之 DebugConsole
    Unity-WIKI 之 DrawArrow
    Unity 2D Sprite Lighting
    Unity 2D Touch Movement
    [Unity2D]2D Mobile Joystick
    DragRigidbody2D
    Finger Gestures 3.1
    2D Skeletal Animation Ready
  • 原文地址:https://www.cnblogs.com/dong-/p/9880049.html
Copyright © 2011-2022 走看看