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