權限管理——版本2
阿新 • • 發佈:2018-03-10
數據結構 hasclass 只需要 site sta print basepage closed asdasdas
權限管理——版本2
1.完成目標
菜單相關: [ {‘menu_id‘:1,‘menu_title‘:‘菜單1‘,‘title‘:‘用戶列表‘,‘url‘:‘/userinfo/‘}, {‘menu_id‘:1,‘menu_title‘:‘菜單1‘,‘title‘:‘訂單列表‘,‘url‘:‘/order/‘}, {‘menu_id‘:2,‘menu_title‘:‘菜單2‘,‘title‘:‘xxx列表‘,‘url‘:‘/xxx/‘}, {‘menu_id‘:3,‘menu_title‘:‘菜單2‘,‘title‘:‘aaa列表‘,‘url‘:‘/aaa/‘}, ] 菜單1 用戶管理 菜單2 訂單管理 分級,默認展開選中。 構建數據結構: { 1: { ‘menu_id‘: 1, ‘menu_title‘: ‘菜單一‘, ‘active‘: None, ‘children‘: [ {‘title‘: ‘訂單列表‘, ‘url‘: ‘/order/‘, ‘active‘: None} ] } 2: { ‘menu_id‘: 2, ‘menu_title‘: ‘菜單二‘, ‘active‘: True, ‘children‘: [ {‘title‘: ‘用戶列表‘, ‘url‘: ‘/userinfo/‘, ‘active‘: True} ] }, } 小結: 菜單相關的數據結構,還需要和當前請求的url匹配,匹配成功,actice為True。 active有兩個操作: 1.目標是否變紅 2.目標是否展開或縮小。
5.從構建數據結構傳過來的數據格式變了: 做了一個settings配置名,改以下就不需要每個地方都改。
6.循環數據,拿字典裏面的key,value,字典套字典,要學會取值。
7.為了讓視圖知道codes,我們還需要取codes。
8.把生成菜單的標簽放到simple_tag裏load就可以了
9.擴展一個inclusion_tag自定義頁面的功能,後面只需要跟一個頁面。
結果實例圖:
2.代碼
1.app01/views.py
from django.shortcuts import render,redirect,HttpResponse from rbac import models from rbac.service.init_permission import init_permission from django.conf import settings import re def login(reqeust): if reqeust.method == ‘GET‘: return render(reqeust,‘login.html‘) else: user = reqeust.POST.get(‘user‘) pwd = reqeust.POST.get(‘pwd‘) print(reqeust.POST) user = models.User.objects.filter(username=user,password=pwd).first() print(user) if not user: return render(reqeust,‘login.html‘) init_permission(user,reqeust) print(111) return redirect(‘/index/‘) def index(request): print(222) return HttpResponse(‘歡迎登錄 哈哈哈‘) class BasePagePermission(object): def __init__(self,code_list): self.code_list = code_list def has_add(self): if ‘add‘ in self.code_list: return True def has_edit(self): if ‘edit‘ in self.code_list: return True def has_del(self): if ‘del‘ in self.code_list: return True def userinfo(request): print(request.permisstion_code_list) page_permission = BasePagePermission(request.permisstion_code_list) data_list = [ {‘id‘:1,‘name‘:‘xxx1‘}, {‘id‘:2,‘name‘:‘xxx2‘}, {‘id‘:3,‘name‘:‘xxx3‘}, {‘id‘:4,‘name‘:‘xxx4‘}, {‘id‘:5,‘name‘:‘xxx5‘}, ] menu_list = request.session[settings.PERMISSTION_MENU_KEY] return render(request,‘userinfo.html‘,{‘data_list‘:data_list,‘page_permission‘:page_permission}) def userinfo_add(request): page_permission = BasePagePermission(request.permisstion_code_list) return HttpResponse(‘添加用戶頁面‘) class OrderPagePermission(BasePagePermission): def has_report(self): if ‘report‘ in self.code_list: return True def order(request): order_permission = OrderPagePermission(request.permisstion_code_list) return render(request, ‘order.html‘)views.py
2.settings:
STATIC_URL = ‘/static/‘ PERMISSTION_URL_DICT = ‘permissions_url_dict‘ PERMISSTION_MENU_KEY = ‘asdasdasdada‘ VALID_URL = [ ‘/login/‘, ‘/admin.*/‘ ]
3.urls.py
from django.conf.urls import url from django.contrib import admin from rbac import views from app01 import views as app01_views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^test/‘,views.test), url(r‘^login/‘,app01_views.login), url(r‘^index/‘,app01_views.index), url(r‘^userinfo/$‘,app01_views.userinfo), url(r‘^userinfo/add$‘,app01_views.userinfo_add), url(r‘^order/$‘,app01_views.order) ]
4.rbac/middlewares/rbac.py
import re from permission import settings from django.shortcuts import redirect,HttpResponse class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, ‘process_request‘): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, ‘process_response‘): response = self.process_response(request, response) return response class RbacMiddleware(MiddlewareMixin): def process_request(self,request): ‘‘‘ 1.獲取當前請求的url: 使用 request.path_info 2.獲取session中的保存的用戶權限: 使用request.session.get().不能request.session[],因為可能沒數據。 3.設置白名單,獲取到白名單的放行數據,和用戶所擁有的權限url,匹配。 如果匹配,就不需要經過權限的檢查。 4.當用戶訪問了組的列表頁面後,就應該知道他在這個組裏還有什麽權限。 -1.分組: 1可以是用戶組, 2是訂單組 -2.不當是用戶列表頁面需要知道他的所有權限,其它頁面也應該知道。使用codes來獲取。 -3. 以上這樣設置,不管什麽頁面都能知道所有的權限url,找到codes就可以。 list = { 1:{ ‘codes‘:[‘list‘,‘add‘,‘edit‘,‘del‘] ‘urls‘:[ /userinfo/ /userinfo/add/ /userinfo/edit/(\d+)/ /userinfo/del/(\d+)/ ] } } 5.從構建數據結構傳過來的數據格式變了: 做了一個settings配置名,改以下就不需要每個地方都改。 6.循環數據,拿字典裏面的key,value,字典套字典,要學會取值。 7.為了讓視圖知道codes,我們還需要取codes。 8.把生成菜單的標簽放到simple_tag裏load就可以了 9.擴展一個inclusion_tag自定義頁面的後面只需要跟一個頁面。 ‘‘‘ current_url = request.path_info for url in settings.VALID_URL: if re.match(url,current_url): print(url,current_url) return None permission_dict = request.session.get(settings.PERMISSTION_URL_DICT) # 拿到url格式的數據 if not permission_dict: return redirect(‘/login/‘) flag = False for group_id,code_url in permission_dict.items(): # 用in不行,含正則的url使用in會匹配不了,所要要用正則:re.match for db_url in code_url[‘urls‘]: regax = ‘^{0}$‘.format(db_url) #加上起止符,絕對匹配。 if re.match(regax, current_url): # 如果匹配成功,就已等 request.permisstion_code_list = code_url[‘codes‘] #取到codes列表,存到request裏 flag = True break if flag: break if not flag: return HttpResponse(‘無權訪問‘)rbac.py
5.rbac/service/init_permission.py
from django.conf import settings def init_permission(user,request): ‘‘‘ 初始化權限信息,把權限url放到session。 :param user: :param request: :return: list = { 1:{ ‘codes‘:[‘list‘,‘add‘,‘edit‘,‘del‘] ‘urls‘:[ /userinfo/ /userinfo/add/ /userinfo/edit/(\d+)/ /userinfo/del/(\d+)/ ] } } 菜單相關: [ {‘menu_id‘:1,‘menu_title‘:‘菜單1‘,‘title‘:‘用戶列表‘,‘url‘:‘/userinfo/‘}, {‘menu_id‘:1,‘menu_title‘:‘菜單1‘,‘title‘:‘訂單列表‘,‘url‘:‘/order/‘}, {‘menu_id‘:2,‘menu_title‘:‘菜單2‘,‘title‘:‘xxx列表‘,‘url‘:‘/xxx/‘}, {‘menu_id‘:3,‘menu_title‘:‘菜單2‘,‘title‘:‘aaa列表‘,‘url‘:‘/aaa/‘}, ] 菜單1 用戶管理 菜單2 訂單管理 分級,默認展開選中。 構建數據結構: { 1: { ‘menu_id‘: 1, ‘menu_title‘: ‘菜單一‘, ‘active‘: None, ‘children‘: [ {‘title‘: ‘訂單列表‘, ‘url‘: ‘/order/‘, ‘active‘: None} ] } 2: { ‘menu_id‘: 2, ‘menu_title‘: ‘菜單二‘, ‘active‘: True, ‘children‘: [ {‘title‘: ‘用戶列表‘, ‘url‘: ‘/userinfo/‘, ‘active‘: True} ] }, } 小結: 菜單相關的數據結構,還需要和當前請求的url匹配,匹配成功,actice為True。 active有兩個操作: 1.目標是否變紅 2.目標是否展開或縮小。 ‘‘‘ permission_list2 = user.roles.values(‘permissions__title‘, #權限名稱 ‘permissions__url‘, #權限url ‘permissions__is_menu‘, #權限是否是菜單 ‘permissions__codes‘, #權限的codes ‘permissions__group_id‘, #組id ‘permissions__group__menu_id‘, #菜單id ‘permissions__group__menu__title‘ #菜單名稱 ).distinct() menu_list = [] #去掉不是菜單的url for item in permission_list2: if not item[‘permissions__is_menu‘]: continue tpl = { ‘menu_id‘:item[‘permissions__group__menu_id‘], ‘menu_title‘:item[‘permissions__group__menu__title‘], ‘title‘:item[‘permissions__title‘], ‘url‘:item[‘permissions__url‘], ‘active‘:False } menu_list.append(tpl) request.session[settings.PERMISSTION_MENU_KEY] = menu_list #權限相關 result = {} for item in permission_list2: group_id = item[‘permissions__group_id‘] code = item[‘permissions__codes‘] url = item[‘permissions__url‘] if group_id in result: result[group_id][‘codes‘].append(code) result[group_id][‘urls‘].append(url) else: result[group_id] = { ‘codes‘:[code,], ‘urls‘:[url,], } request.session[settings.PERMISSTION_URL_DICT] = result #拿到用戶請求url,和session做對比,如果在,可訪問,不在,一邊去。View Code
6.rbac/static/rabc/rbac.css
.item-permission{ padding: 3px 10px; } .item-permission a{ display: block; } .item-permission a.active{ color: red; } .hide{ display: none; }View Code
7..rbac/static/rabc/rbac.js
/** * Created by Administrator on 2017/11/8. */ $(function () { $(‘.item-title‘).click(function () { if($(this).next().hasClass(‘hide‘)){ $(this).next().removeClass(‘hide‘) }else{ $(this).next().addClass(‘hide‘) } }) });
8.rbac/templatetags/rbac.py
import re from django.template import Library from django.conf import settings register = Library() @register.inclusion_tag(‘xxxxx.html‘) def menu_html(request): ‘‘‘ 去session中獲取菜單相關信息,匹配當前url,生成菜單。 :param request: :return: ‘‘‘ menu_list = request.session[settings.PERMISSTION_MENU_KEY] current_url = request.path_info result = {} for item in menu_list: url = item[‘url‘] print(url) regex = ‘^{0}$‘.format(url) active = False if re.match(regex,current_url): active = True menu_id = item[‘menu_id‘] if menu_id in result: result[menu_id][‘children‘].append({‘title‘:item[‘title‘],‘url‘:item[‘url‘],‘active‘:active}) if active: result[menu_id][‘active‘] = True else: result[menu_id] = { ‘menu_id‘:menu_id, ‘menu_title‘:item[‘menu_title‘], ‘active‘: active, ‘children‘: [ {‘title‘: item[‘title‘], ‘url‘: item[‘url‘], ‘active‘: active}, ] } return {‘menu_dict‘:result}View Code
9.xxxxx.html
{% for k,item in menu_dict.items %} <div class="item"> <div class="item-title">{{ item.menu_title }}</div> {% if item.active %} <div class="item-permission"> {% else %} <div class="item-permission hide"> {% endif %} {% for v in item.children %} {% if v.active %} <a href="{{ v.url }}" class="active">{{ v.title }}</a> {% else %} <a href="{{ v.url }}">{{ v.title }}</a> {% endif %} {% endfor %} </div> </div> {% endfor %}
權限管理——版本2