對於Django而言,雖然自帶了一些基本的通用權限限制,但現實中,可能我們更希望自己去定義業務權限划分
Django對於權限這塊的部分驗證方法
1 user = request.user 2 user.is_superuser #是否是超級管理員 3 user.s_anonymous() #是否匿名用戶,及未登錄用戶 4 user.groups.select_related() #獲取用戶對應的組角色對象, 5 #當獲取到group后,通過group.name獲取組名,
下面是一段完整的權限控制例子
1 #!/usr/bin/env python 2 # encoding:utf8 3 4 from django.core.urlresolvers import resolve 5 from django.shortcuts import render 6 7 8 # 定義角色權限 9 roles = { 10 'consultant': ['Customer', 'ConsultRecord'], 11 'teachers': ['Course', 'ClassList', 'CourseRecord', 'StudyRecord'], 12 'students': ['StudyRecord'], 13 } 14 # 權限映射 15 permission_map = { 16 'view_home': ['index', 'GET', []], # 展示對應對可操作對象 17 'view_object': ['admin_controller', 'GET', ['show']], # 查看具體對象對數據信息 18 'edit_object': ['admin_controller', 'POST', ['show', 'id']], # 具有編輯該對象對權限 19 'add_object_view': ['admin_controller', 'GET', ['add']], # 進入添加頁面,但不表示可以進行修改,該權限用於對表格顯示字段過長,顯示不全,可以進入該頁面查看 20 'add_object': ['admin_controller', 'POST', ['add']], # 具有添加該對象對權限 21 'delete_object': ['admin_controller', 'POST', ['show', 'data']], # 具有刪除該對象對權限 22 } 23 24 25 def check_process(*args, **kwargs): 26 request = args[0] 27 user = request.user 28 if user.is_superuser: 29 return True 30 resolver_match_obj = resolve(request.path) 31 url_name = resolver_match_obj.url_name 32 args = list(resolver_match_obj.args) 33 args.extend(request.GET) 34 args.extend(request.POST) 35 print('begin checking permission ', resolver_match_obj) 36 if url_name: 37 is_match = False 38 match_perm = None 39 for permission in permission_map: 40 permission_action = permission_map[permission] # 獲取url對應的權限動作 41 print('----------------url action: ', permission_action) 42 if len(permission_action) == 3: # 為保障下面語句執行不為語法而被破壞,加上該條件,強制性判斷,否則放行 43 define_url_name, define_request_method, define_others = permission_action 44 if url_name == define_url_name: 45 print("match url name: ", define_url_name) 46 if request.method == define_request_method: 47 print("match method: ", define_request_method) 48 if define_others: # 如果定義了具體參數匹配,則繼續匹配參數 49 print("check others: ", permission, define_others) 50 for arg in define_others: 51 if hasattr(request, str(define_request_method)): 52 request_method = getattr(request, str(define_request_method)) # 獲取對應的請求方法對象 53 if hasattr(request_method, arg) or arg in args: # 如果能匹配參數,則標記匹配 54 is_match = True 55 print("others match: ", arg) 56 else: 57 print("others not match: ", arg) 58 is_match = False 59 if is_match: 60 print("others match done: ", permission, permission_action) 61 match_perm = permission 62 break 63 else: 64 is_match = True 65 match_perm = permission 66 print("url check done ...", permission, permission_action) 67 break 68 else: 69 print('please check the define rules, maybe has some problem') 70 return True # 如果定義的動作不完整,為避免新增權限的缺陷影響業務,這種錯誤應該放行處理 71 else: 72 return True # 如果沒有找到對應的url name則放行處理 73 74 if is_match: 75 print("begin check user permission ...") 76 if user.is_anonymous(): 77 print("user has not login ...") 78 return True # 如果用戶是匿名,說明該頁面可能不需要權限控制,放行處理,假如該view需要登錄認證,那么再次權限處理時,不會在此處理 79 elif user.has_perm('%s.%s' % (__package__, match_perm)): 80 groups = user.groups.select_related() 81 model_list = [] 82 for group in groups: 83 if group.name in roles: 84 model_list.extend(roles[group.name]) 85 if args and len(args) > 1: # 如果URL獲取到參數,則對參數進行比較 86 access_model = args[0] 87 if access_model not in model_list: # 該操作主要攔截,直接使用URL方式而非超鏈接,嘗試指定不同model訪問其它數據 88 return False 89 return True 90 return model_list if model_list else True # 如果model_list為空,且該用戶還有權限,那么只有超級用戶才有這種特權了 91 return False 92 93 94 def decorator(func): 95 def wrapper(*args, **kwargs): 96 check_result = check_process(*args, **kwargs) 97 if not check_result: 98 render_respond = render(args[0], '403.html') 99 render_respond.status_code = 403 # 修改頭部信息狀態碼 100 print("permission refused ...") 101 return render_respond 102 if type(check_result) is list: # 該參數僅在本次view中可能有用,所以在return時需要嘗試捕獲,如果出錯,則嘗試移除該key,再返回,再有其它錯誤,就可以排除是該權限控制產生的了 103 kwargs['model_list'] = check_result 104 print('permission check passed...') 105 try: 106 return func(*args, **kwargs) 107 except TypeError: 108 kwargs.pop('model_list') 109 return func(*args, **kwargs) 110 return wrapper