crm 动态一级二级菜单

之前代码菜单是写是的

如何 让他 动态 生成了  首先 添加 2个字段

admin.py 更改 显示

from django.contrib import admin
from rbac import models

# Register your models here.

class PermissionAdmin(admin.ModelAdmin):
    list_display = ['url', 'title','is_menu','icon']#列表显示
    list_editable = ['title','is_menu','icon']#可编辑
admin.site.register(models.Permission, PermissionAdmin)
admin.site.register(models.Role)
admin.site.register(models.User)

然后进入 admin 把设为 一级菜单的 图标设置上去

auth.py 进行 mode筛选

def login(request):
    if request.method == 'POST':
        # 获取用户名和密码
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        # 去数剧库进行筛选
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html')
        permission_query = obj.roles.filter(permissions__url__isnull=False).values('permissions__url',
         'permissions__title','permissions__is_menu','permissions__icon').distinct()
        #通过查询到的用户的obj反查角色表,values 正向查询当前用户的权限表的url信息 title

        permission_list=[]#存放权限信息
        menu_list=[]#存放菜单信息
        for item in permission_query:
            permission_list.append({'url':item['permissions__url']})
            if item.get('permissions__is_menu'):
                menu_list.append({'url':item['permissions__url'],'icon':item['permissions__icon'],'title':item['permissions__title']})

        # print('1111',permission_query)  # <QuerySet [{'permissions__url': '/index/', 'permissions__title': '首页'}]>
        #将权限信息写入到session
        request.session[settings.PERMISSION_SESSION_KEY]=permission_list
        #将菜单 信息 写入session
        request.session[settings.MENU_SESSION_KEY]=menu_list
        request.session['is_login'] = True
        return redirect(reverse('index'))
    return render(request, 'login.html')

settings.py中定义

# 白名单
WHITE_LIST = [
    r'^/login/$',
    r'^/reg/$',
    r'^/admin/.*',
]
# 免认证的地址  需要登录 不行权限校验
NO_PERMISSION_LIST = [
    '/index/'
]
#权限信息url key
PERMISSION_SESSION_KEY='permissions'
#存放菜单信息
MENU_SESSION_KEY='menus'

更改一下 rbacapp中  更改 中间件中 middlewares/rbac.py 相应的值

        # 获取当前用户的权限
        permission_list = request.session[settings.PERMISSION_SESSION_KEY]
        print(permission_list)
        # 权限的校验
        for i in permission_list:
            if re.match('^{}$'.format(i['url']), url):
                return
        # 没匹配成功  没有权限
        return HttpResponse('没有访问的权限')

layout.html中 跟改显示   这样虽然成功了 但是还是写死了menus

            <div class="static-menu">
{#                <a href="/customer/list/" class="active">#}
{#                    <span class="icon-wrap"><i class="fa fa-connectdevelop"></i></span> 客户管理</a>#}
{#                <a href="/payment/list/">#}
{#                    <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> 账单管理</a>#}
                {% for item in request.session.menus %}
                    <a href="{{ item.url }}">
                    <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> {{ item.title }}</a>
                {% endfor %}
            </div>

如何解决?

自定义 inclusion_tag

创建 templatetags目录   rbac.py

from django import  template
from django.conf import  settings
register=template.Library()
import re
@register.inclusion_tag('menu.html')
def menu(request):
    menu_list=request.session.get(settings.MENU_SESSION_KEY)
    for item in menu_list:
        url=item['url']
        if re.match('^{}$'.format(url),request.path_info):
            item['class']='active'
    return  {'menu_list':menu_list}

menu.html

            <div class="static-menu">
                {% for item in menu_list%}
                    <a href="{{ item.url }}" class="{{ item.class }}">
                    <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> {{ item.title }}</a>
                {% endfor %}
            </div>

为了 下次 直接调用rbac 整合

把之前的判断 web views中的auth.py中的 查询写入session部分 移动到rbac/server/init_permission.py

from django.conf import settings
def init_permission(request, obj):
    permission_query = obj.roles.filter(permissions__url__isnull=False).values('permissions__url',
                                                                               'permissions__title',
                                                                               'permissions__is_menu',
                                                                               'permissions__icon').distinct()
    permission_list = []  # 存放权限
    menu_list = []  # 存放菜单信息
    for item in permission_query:
        permission_list.append({'url': item['permissions__url']})
        if item.get('permissions__is_menu'):
            menu_list.append({'url': item['permissions__url'], 'icon': item['permissions__icon'],
                              'title': item['permissions__title']})
    # 将权限写入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_list
    # 将菜单写入 session
    request.session[settings.MENU_SESSION_KEY] = menu_list
    request.session['is_login'] = True
        if not obj:
            return redirect(reverse('login'))
        # 认证成功 进行权限信息初始化(权限、菜单)
        init_permission(request, obj)
        return redirect(reverse('index'))

把 web下的 templatetags 移动到rbac app下

自定义标签inclusion

把menu.html  移动到新建templates/rbac/中

 

把 css部分 移动到 static/css/menu.css

二级菜单调用自动生成

更改modes中的表字段 添加 menu表

进入 admin 进行 权限 划分

 

 更改 server permission.py

    # 权限的列表
    permission_list = []

    # 菜单的字典
    menu_dict ={}

    for i in permission_query:
        # 把权限的信息放入permission_list
        permission_list.append({'url': i['permissions__url']})

        menu_id = i.get('permissions__menu_id')

        if not menu_id:
            continue

        menu_dict.setdefault(menu_id, {
            'title': i['permissions__menu__title'],
            'icon': i['permissions__menu__icon'],
            'children': [

            ]
        })

        menu_dict[menu_id]['children'].append({'title': i['permissions__title'], 'url': i['permissions__url']})

 

from django import template
from django.conf import settings
import re

register = template.Library()


@register.inclusion_tag('rbac/menu.html')
def menu(request):
    menu_dict = request.session[settings.MENU_SESSION_KEY]

    return {'menu_list': menu_dict.values()}

 

rbac/static/rbac/css/menu.css

.left-menu .menu-body .static-menu {

}

.left-menu .menu-body .static-menu .icon-wrap {
    width: 20px;
    display: inline-block;
    text-align: center;
}

.left-menu .menu-body .static-menu a {
    text-decoration: none;
    padding: 8px 15px;
    border-bottom: 1px solid #ccc;
    color: #333;
    display: block;
    background: #efefef;
    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
    background: -ms-linear-gradient(bottom, #efefef, #fafafa);
    background: -moz-linear-gradient(center bottom, #efefef 0%, #fafafa 100%);
    background: -o-linear-gradient(bottom, #efefef, #fafafa);
    filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
    box-shadow: inset 0px 1px 1px white;
}

.left-menu .menu-body .static-menu a:hover {
    color: #2F72AB;
    border-left: 2px solid #2F72AB;
}

.left-menu .menu-body .static-menu a.active {
    color: #2F72AB;
    border-left: 2px solid #2F72AB;
}


.multi-menu .item {
    background-color: white;
}

.multi-menu .item > .title {
    padding: 10px 5px;
    border-bottom: 1px solid #dddddd;
    cursor: pointer;
    color: #333;
    display: block;
    background: #efefef;
    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
    background: -ms-linear-gradient(bottom, #efefef, #fafafa);
    background: -o-linear-gradient(bottom, #efefef, #fafafa);
    filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
    box-shadow: inset 0 1px 1px white;
}

.multi-menu .item > .body {
    border-bottom: 1px solid #dddddd;
}

.multi-menu .item > .body a {
    display: block;
    padding: 5px 20px;
    text-decoration: none;
    border-left: 2px solid transparent;
    font-size: 13px;

}

.multi-menu .item > .body a:hover {
    border-left: 2px solid #2F72AB;
}

.multi-menu .item > .body a.active {
    border-left: 2px solid #2F72AB;
}
View Code

 

<div class="multi-menu">

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

            </div>

        </div>

    {% endfor %}


</div>

layout.html应用上

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>路飞学城</title>
    <link rel="shortcut icon" href="{% static 'imgs/luffy-study-logo.png' %} ">
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.css' %} "/>
    <link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.css' %} "/>
    <link rel="stylesheet" href="{% static 'css/commons.css' %} "/>
    <link rel="stylesheet" href="{% static 'css/nav.css' %} "/>
    <link rel="stylesheet" href="{% static 'rbac/css/menu.css' %} "/>
    <style>
        body {
            margin: 0;
        }

        .no-radius {
            border-radius: 0;
        }

        .no-margin {
            margin: 0;
        }

        .pg-body > .left-menu {
            background-color: #EAEDF1;
            position: absolute;
            left: 1px;
            top: 48px;
            bottom: 0;
            width: 220px;
            border: 1px solid #EAEDF1;
            overflow: auto;
        }

        .pg-body > .right-body {
            position: absolute;
            left: 225px;
            right: 0;
            top: 48px;
            bottom: 0;
            overflow: scroll;
            border: 1px solid #ddd;
            border-top: 0;
            font-size: 13px;
            min-width: 755px;
        }

        .navbar-right {
            float: right !important;
            margin-right: -15px;
        }

        .luffy-container {
            padding: 15px;
        }


    </style>

</head>
<body>

<div class="pg-header">
    <div class="nav">
        <div class="logo-area left">
            <a href="#">
                <img class="logo" src="{% static 'imgs/logo.svg' %}">
                <span style="font-size: 18px;">路飞学城 </span>
            </a>
        </div>

        <div class="left-menu left">
            <a class="menu-item">资产管理</a>
            <a class="menu-item">用户信息</a>
            <a class="menu-item">路飞管理</a>
            <div class="menu-item">
                <span>使用说明</span>
                <i class="fa fa-caret-down" aria-hidden="true"></i>
                <div class="more-info">
                    <a href="#" class="more-item">管他什么菜单</a>
                    <a href="#" class="more-item">实在是编不了</a>
                </div>
            </div>
        </div>

        <div class="right-menu right clearfix">

            <div class="user-info right">
                <a href="#" class="avatar">
                    <img class="img-circle" src="{% static 'imgs/default.png' %}">
                </a>

                <div class="more-info">
                    <a href="#" class="more-item">个人信息</a>
                    <a href="#" class="more-item">注销</a>
                </div>
            </div>

            <a class="user-menu right">
                消息
                <i class="fa fa-commenting-o" aria-hidden="true"></i>
                <span class="badge bg-success">2</span>
            </a>

            <a class="user-menu right">
                通知
                <i class="fa fa-envelope-o" aria-hidden="true"></i>
                <span class="badge bg-success">2</span>
            </a>

            <a class="user-menu right">
                任务
                <i class="fa fa-bell-o" aria-hidden="true"></i>
                <span class="badge bg-danger">4</span>
            </a>
        </div>

    </div>
</div>
<div class="pg-body">
    <div class="left-menu">
        <div class="menu-body">

            {#                <a href="/customer/list/" class="active">#}
            {#                    <span class="icon-wrap"><i class="fa fa-connectdevelop"></i></span> 客户管理</a>#}
            {#                <a href="/payment/list/">#}
            {#                    <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> 账单管理</a>#}
            {% load rbac %}
            {% menu request %}


        </div>
    </div>
    <div class="right-body">
        <div>
            <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;">

                <li><a href="#">首页</a></li>
                <li class="active">客户管理</li>

            </ol>
        </div>
        {% block content %} {% endblock %}
    </div>
</div>


<script src="{% static 'js/jquery-3.3.1.min.js' %} "></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.js' %} "></script>

<script>
    $('.multi-menu .title').click(function () {
        $(this).next().toggleClass('hide')

    })


</script>

{% block js %} {% endblock %}
</body>
</html>

 

posted @ 2019-03-21 00:18  崽崽1573  阅读(533)  评论(0编辑  收藏  举报