1 封装成组件html
1 新建一个app abcv 2 建一个middleware.py (中间件) 和 p_input.py imp models def i_p(re,usr):权限 view里 i_P(request,user) 传过来 3 setting引入abcv.middl
# 左侧菜单 {%menu request%} 自定义标签 inclusion_tag('rbac/menu.html') #村长写
admin前端
list_editable = ['url', ] #能够编辑 list_display = ['url',] bool是x
layout.htmlpython
layout是模板 class ='fa {{ foo.icon }}' 引进的图标 {% include 'result.html'} 页面引入
menu.htmlweb
标签处于选中状态 前端能够 在后端给他加 class: active #这个 写活的 中间件 装饰器 和自定义标签 都行。 写死 customer for item in request.session['permisson_menu_list'] #if request.url == item['url']: if re.match('^{}$'.format(item['url']),request.url) # 添加/d的更好 item['class'] = 'active'
rbac权限django
1准备表后端
class User(models.Model): class Role(models.Model): class Permission(models.Model): 给角色以权限 给用户以角色
2 用户登录 , 登录成功以后,将用户的信息和用户的权限信息都注入到了session中服务器
perssions = mod.Per.ob.filter(role__user__name=user__obj.name).distinct() permission_list = [i.url for i in permissions] request.session['permission_list'] = permission_list
3 中间件 权限认证session
白名单放行 for i in ['/login/','/admin/.*'] : ret = re.search(i,req.pa) if ret : return None (放行) 登录认证 user = request.sesion.get('user') if not user: return red() 权限认证 for item in request.session['permission_list']: reg = '^%s$'%item ret = re.search(reg,requst.path) if ret:rN
左边菜单 : 登录的身份不一样,显示的菜单(操做)不一样app
tools--run manage.py --startapp rbac 建立一个app函数
新建一个serveice 文件夹
把中间件程序写入文件夹(而且改setting的路径) 新建permission_inpu.py文件 在rabc.serveice.per_input 里引入models 写权限函数i_p view 里引入 rbac.serveice.permission_input.initial_session 注入封装的 传过去 initial_session(request,user_obj)
分红了两个app,第一个app是功能菜单,第二个app是权限注入
url'r^" 都过来 include 路由分发 发到web.urls里
layout.html 全部的html文件都是集成的这个html文件
1. 怎么区别那个是左侧的 Permission表里字段 is_menu 是不是菜单 2. admin 里 list_editable = ['url','is_menu','icon(图标)'] list_display = ['url','is_menu','icon(图标)'] 能够修改 list_display = ['url','is_menu','icon(图标)'] 只是展现 fa-code-fork 图标fa开头fontawesome 阿里的 3 两个static 不是一个同级的外部文件(各用个的吗 ) 要上线外部文件不是放在Django,有专门的静态文件返回的服务器 或者是'/templates/login.html'
permission_input.py de def initial_session(request,user): 展现不一样——改。分左侧右侧了 从新取is_menu(标志) permission = m.P.o.f(role__user__name=user_obj).distinct( for item in permission: permission_list.append(item.url) if item.is_menu: per_menu_list.append({ title:item.title, 'url':item.url, 'icon':item.icon, }) request.session['permission_list'] = permission_list request.session['permission_menu_list'] = permission_menu_list 生成menu的时候和验证的时候组成一套
layout.html
... {% for foo in request.session.permission_menu_list} div a {{foo.url}} #万能的句点号 a href == '{foo.url}' >{{foo.title}}< {%endfor}
rbac.py
自定义标签 from django.conf import settings import re @register.inclusion_tag('rbac/menu.html') def menu(request): menu_list = request.session['permission_menu_list'] for item in menu_list: url = item['url'] if re.match('^{}$'.format(url),request.path_info): item['class'] = 'active' break return {'menu_list':menu_list} # 等于 render{'menu.thml',{'date':date} } # 等于 include 'menu.html' =组件引入 引入以前把数据给返过去了
过滤器存在的意义: 复用
多了就好用了 ,逻辑多了不用重复写
from django.utils.safestring import mark_safe return mark_safe('<h1>自定义标签</h1>') 这种格式才能保存h1的功能 not # return '<h1>自定义标签</h1>' 定义 @register.filter def ff(v1,v2 = None): # return '<h1>自定义标签</h1>' return mark_safe('<h1>自定义标签</h1>') 调用 {% load xx %} {{ num|ff:'2'}} def tag(num): return 自定义标签 @register.simple_tag def ftag(num): return '自定义标签' {% ftag num %} 调用顺序相反 + {% %} 自定义标签 @register.inclusion_tag('result.html') def intag(num): return {'data':[11,22,33]} result.html {% for i in data %} {{ i }} {% endfor %} test.html {% load xx %} {% intag num%}
单个函数写添加 缺点:每一个函数都写一遍 多则不行 少也代码多 def customer_lis(request): data_list = models.Customer.objects.all() for item in request.session['permission_menu_list']: if item['url'] == request.path: item['class'] = 'active' return render(request,'custom.html',{'data_list':data_list}) menu.html {%for item in menu_list a href = url 'class' = ‘{{item.class}}’
写装饰器也能够
自定义标签也能够 inclusion_tag()
@register.inclusion_tag('rbac/menu.html') def menu(request): menu_list = request.session.get('permission_menu_list') # 左侧菜单栏的列表里面 for item in menu_list: if re.match('^{}$'.format(item['url']),reqeust.path): item['class'] = 'active' break return {'menu_list':menu_list}
user_obj - - permission_list = ['/customer/list','/customer/add/'...] permission_menu_list = [ {'title':客户列表,‘url’:'/customer/list/'}, {'title':缴费列表,‘url’:'/payment/list/'},] @inclusion_tag('menu.html') def menu(request): menu_list = request.session['perssion_menu_list'] return {'menu_list':menu_list} menu.html {%for item in menu_list%} custmoer.html {%extends 'layout.html'%} {%menu request%}
models.py
from django.db import models class User(models.Model): name = models.Ch(32) pwd也是 roles = models.ManyToManyField('Role') def_str_(self) : re self.name class Role() title 32 Permissions = MTM('Permission') str:tit class Permission() title url 32 str_ : title
admin.py
admin 只有一张表 为了操做 models 添加models, 引入为 admin.site.register(models.Role)
自定义一下,加样式
class PermissionAdmin(admin.ModelAdmin): list_display = ['pk','title','url'] 显示 list_editable = ['title','url'] 能够编辑 ‘pk’不可编辑 ordering = ['-pk'] 倒叙 admin.site.register(models.Permission,PermissionAdmin)
view.py
def login(request): user = request.POST.get('user') pwd = request.POST.get('pwd') user_obj =models.User.objects.filter(name=user,pwd=pwd).first() if user_obj: #登陆成功,保存登陆状态 request.session['user'] = user_obj.name #查询权限,保存到session permissions = models.Permission.objects.filter(role__user__name=user_obj.name).distinct() permission_list = [i.url for i in permissions] request.session['permission_list'] = permission_list
middleware.py (权限认证)
白名单放行 if request.path in ['/login/']: return None if re.search('/admin/',request.path): return None 登陆认证 user = request.session.get('user') if not user: return redirect('login') 权限认证 for item in request.session['permisson_list']: reg = '%s$'%item ret = re.search(reg,request.path) if ret: return None else: return HttpResponse('很差意思,权限不够!!无权访问')
1 白名单放行
if request.path in ['/login/']: return None
不是
if request.path in ['login']: return None