首页 > 其他 > 详细

crm-4权限

时间:2019-09-29 14:57:35      阅读:68      评论:0      收藏:0      [点我收藏+]

1.rbac-优化login函数  

  因为login是业务逻辑 ,而rbac是个组件 ,将rbac在login的代码分离

技术分享图片
###初始化权限函数分离出去 rbac/service/permission
from untitled import settings

def init_permission(request, obj):
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
        permissions__title,
        permissions__url,
        permissions__is_menu,
        permissions__name,
    ).distinct()

    permission_dict = {}
    menu_list = []

    for i in permission_query:
        permission_dict[i[permissions__name]] = {url: i[permissions__url]}
        if i[permissions__is_menu]:
            menu_list.append({title: i[permissions__title], url: i[permissions__url]})

    # 将对象列表转换为列表 ! 并将用户权限存入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
    request.session[settings.MENU_SESSION_KEY] = menu_list
    # 此刻该用户登录成功
    request.session[is_login] = True


###login函数直接使用
class login(View):
    def get(self, request):
        return render(request, login.html)

    def post(self, request):
        name = request.POST.get(username)
        password = request.POST.get(password)
        md5 = hashlib.md5()
        md5.update(password.encode(utf-8))
        md5_pwd = md5.hexdigest()
        print(md5_pwd, name)
        obj = models.User.objects.filter(name=name, password=md5_pwd).first()
        if not obj:
            return HttpResponse(账号密码错误)
        # 初始化用户权限
        else:
            init_permission(request, obj)
        return redirect(reverse(crm:deplist))
View Code

 

2.业务-保留搜索条件

  问题: 在第9页修改了某条数据提交后 ,直接跳到了第1页 ,这是因为视图函数返回到了展示页面没有携带页码

  解决方法:  1.点击修改后的页面url要有上个页面的页码(前端)  2.点击提交数据跳转的页面携带当前页面的页码(view函数)

  思想: 关注request,确保每次访问的url都有页码参数 ,因为request每次请求都会变化,所以每次都要加参数

     定义simple_tag函数返回增加了page参数的url ,前端a标签调用函数获得url

       request.GET.urlencode()     是当前url上的参数

###/rbac/middlewares/my_define
@register.simple_tag
def reverse_url(request, *args, **kwargs):
    # get的参数
    params = request.GET.urlencode()
    # 跳转的url  args[0]是url别名  args[1]是url别名参数
    url = reverse(args[0], args=(args[1],))

    return {}?{}.format(url, params)

###前端html中 执行函数
                {% if request|has_permission:dep_edit %}
                    <td>
                        <a href={% reverse_url request crm:depedit obj.pk %}><i class="fa fa-pencil-square-o"
                                                                                  aria-hidden="true">&nbsp&nbsp&nbsp</i></a>
                        <a class="b1" del_id="{{ obj.pk }}" style="color: red"><i class=" fa fa-remove"
                                                                                  aria-hidden="true"></i></a></td>
                {% endif %}

    修改视图函数中的redirect的值 ,直接拼接上url的参数

      url_name定义为原来reverse的无参数的url

##通用工具utils/reverse_url
from django.urls import reverse


def reverse_url(request, url_name, *args, **kwargs):
    url = reverse(url_name)
    params = request.GET.urlencode()
    return {}?{}.format(url, params)


##跳转页面修改视图函数dep.py
def depadd(request):
....
            return redirect(reverse(crm:deplist))
...

 

3.权限二级菜单

  一级菜单为信息管理

    二级菜单为班级列表与部门列表

  一级菜单为用户管理

    二级菜单为用户列表

  思路: 如果要完成二级菜单 ,我们需要以一级菜单为主导 ,子信息包含二级菜单所有信息 ,根据这个想法我们将取出的权限信息进行分析

  1) 完成models的设计

    新增Menu表用来存储一级菜单 ,和一级菜单的其他信息(样式什么的)

class Menu(models.Model):
    title = models.CharField(菜单名称, max_length=32)
    icon = models.CharField(样式, max_length=128)

    def __str__(self):
        return self.title

    修改Permission表中的is_menu的字段 ,将该字段直接删除 ,信增外键关联Menu表 ,此时所有关联Menu表的权限都是二级菜单 

class Permisssion(models.Model):
    url = models.CharField(含正则url, max_length=128)
    title = models.CharField(中文权限标题, max_length=32, blank=True, null=True)
    name = models.CharField(url的别名, max_length=32, unique=True)
    # is_menu = models.BooleanField(‘是否为菜单‘, default=False)
    menu = models.ForeignKey(Menu, blank=True, null=True)

    def __str__(self):
        return self.title

    修改admin中原来的is_menu消失的字段 ,做数据迁移

  2)新增一级菜单数据  --> 并将权限关联一级菜单

    名称:信息管理   样式:fa-eercast

    名称:用户管理   样式:fa-address-book

  3)重新从权限中获取的管家数据permission_query 

    通过角色表的权限外键获取 : 权限的名字  权限的标题  权限的url  权限的外键id是否为空

    通过角色表的权限外键获取到权限表的Menu外键 : 一级菜单的标题  一级菜单的样式

##原来数据格式
permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
‘permissions__name‘,
‘permissions__title‘,
‘permissions__url‘,
‘permissions__menu_id‘,
‘permissions__menu__title‘,
‘permissions__menu__icon‘,

).distinct() # 对列表中重复的字典进行去重


#
#生成菜单字典的1示例格式 :一级菜单收缩下拉框, 二级菜单作为子值负责跳转url menu_id:{ menu_title: 信息管理, menu_icon: fa-eercast, children: [ { permissions__title: 班级列表 ,url:/crm/class/list }, { permissions__title: 部门管理 ,url:/crm/dep/list } ]
}
技术分享图片
from untitled import settings


def init_permission(request, obj):
    # permission_query是该用户的所有权限 ,从角色表出发 ,根据外键的权限表打印出所有的所需要信息
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
        permissions__name,
        permissions__title,
        permissions__url,
        permissions__menu_id,
        permissions__menu__title,
        permissions__menu__icon,

    ).distinct()  # 对列表中重复的字典进行去重

    permission_dict = {}
    menu_dict = {}

    for i in permission_query:
        # 生成权限字典
        permission_dict[i[permissions__name]] = {url: i[permissions__url]}

        # 生成一级菜单字典
        if i[permissions__menu_id] not in menu_dict:
            menu_dict[permissions__menu_id] = {
                title: i[permissions__menu__title],
                icon: i[pemissions__menu__icon],
                children: [
                    {title: i[permissions__url], url: i[permissions__url]}
                ]
            }
        # 如果字典中有一级菜单的key就可以直接追加一个children了
        else:
            menu_dict[permissions__menu_id][children].append(
                {title: i[permissions__url], url: i[permissions__url]})

    # 将对象列表转换为列表 ! 并将用户权限存入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
    request.session[settings.MENU_SESSION_KEY] = menu_dict
    # 此刻该用户登录成功
    request.session[is_login] = True
View Code

  4) inclusion_tag修改支持一级菜单二级菜单显示 ,并新增权重排序字典 ,和非菜单归属(需要新增weight字段与parent字段 ,博客园自动保存操!你!妈!)


@register.inclusion_tag(‘menu.html‘)
def menu(request):
"""拿出当前url
给所有的一级菜单都hide隐藏
再循环二级菜单 ,如果当前地址匹配到了二级菜单 ,给二级标签重点标记active ,并把一级菜单取出hide
修改后的菜单字典传给前端
"""

# 这个url是当前访问的url
url = request.path_info
menu_dict = request.session[settings.MENU_SESSION_KEY]
permissions_dict = request.session[settings.PERMISSION_SESSION_KEY]

# 非菜单权限归属重新定义url解决
for i in permissions_dict.values():
if re.match(‘^{}$‘.format(i[‘url‘]), url) and i[‘parent‘]:
# 这里将url直接替换为费权限归属的parent__url ,因为该url就是用来生成菜单的
url = i[‘parent‘]
break

# 根据权重将menu_dict变为有序字典
sort_dict = OrderedDict()
temp_lst = sorted(menu_dict, key=lambda x: menu_dict[x][‘weight‘], reverse=True)
for i in temp_lst:
sort_dict[i] = menu_dict[i]

for i in sort_dict.values():

# 开始获取将全部的隐藏 ,仅将匹配到的url取消隐藏
i[‘class‘] = ‘hide‘
for child in i[‘children‘]:
if re.match(‘^{}$‘.format(child[‘url‘]), url):
child[‘class‘] = ‘active‘
i[‘class‘] = ‘‘
return {‘menu_dict‘: sort_dict.values()}
 

    

 4.面包屑功能

  1)拿到对应的数据放入权限字典

        permission_dict[i[permissions__name]] = {url: i[permissions__url],
                                                   title: i[permissions__title],
                                                   parent: i[permissions__parent__url],
                                                   parent_title: i[permissions__parent__title]}

  2)inclusion_tags中定义数据结构 ,将一级菜单和非权限菜单分离 ,放入breadcrum_list列表中

@register.inclusion_tag(breadcrumb.html)
def breadcrum(request):
    url = request.path_info
    permission_dict = request.session[settings.PERMISSION_SESSION_KEY]
    # 导航数据
    breadcrum_list = [{title: 首页, url: /crm/dep/list/, }]

    for i in permission_dict.values():

        # 二级菜单
        if re.match(^{}$.format(i[url]), url) and not i[parent]:
            breadcrum_list.append({title: i[title],
                                   url: i[url], })
            break
        # 非权限菜单
        if re.match(^{}$.format(i[url]), url) and i[parent]:
            breadcrum_list.append({title: i[parent_title], url: i[parent], })
            breadcrum_list.append({title: i[title], url: i[url], })
            break

    return {breadcrum_list: breadcrum_list}

  3)html中展示 ,如果是最后一个不用a标签  ,layout模板引用

####breadcrumb.html
<ol class="breadcrumb">

    {% for breadcrum in breadcrum_list %}
        {% if forloop.last %}
            <li>{{ breadcrum.title }}</li>
        {% else %}
            <li><a href="{{ breadcrum.url }}">{{ breadcrum.title }}</a></li>
        {% endif %}
    {% endfor %}

</ol>

###layout.html
<div class="right-body">
<div>
{% breadcrum request %}
</div>
....

  

    

 

  

 

crm-4权限

原文:https://www.cnblogs.com/quguanwen/p/11459420.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!