Python之路,Day16 - Django 进阶
本节内容
自定义template tags
中间件
CRSF
权限管理
分页
Django分页
https://docs.djangoproject.com/en/1.9/topics/pagination/
自定义template tags
https://docs.djangoproject.com/es/1.9/howto/custom-template-tags/
权限管理
django 自带有基本的权限管理 ,但粒度和限制权限的维度都只是针对具体的表,如果我们想根据业务功能来限制权限,那就得自己写了, 不过也不用完全自己的写,我们可以在django 自带的权限基础上轻松的实现扩展。
自己写权限要注意:
- 权限系统的设计对开发者、用户要实现透明,即他们不需要改变自己原有的使用系统或调用接口的方式
- 权限要易扩展,灵活
- 权限要能实现非常小的粒度的控制,甚至细致到一个按键某个用户是否能按。
想对一个功能实现权限控制,要做到只能过在views方法上加一个装饰器就行了,比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@check_permission @login_required def customer_detail(request,customer_id):
customer_obj = models.Customer.objects.get( id = customer_id)
customer_form = forms.CustomerDetailForm(instance = customer_obj)
if request.method = = 'POST' :
customer_form = forms.CustomerDetailForm(request.POST,instance = customer_obj)
if customer_form.is_valid():
customer_form.save()
parent_base_url = '/' .join(request.path.split( '/' )[: - 2 ])
print ( "url:" ,parent_base_url )
return redirect(parent_base_url)
else :
print (customer_form.errors)
return render(request, 'crm/customer_detail.html' ,{ 'customer_form' :customer_form})
|
check_permission的代码实现
1 #_*_coding:utf-8_*_
2 __author__ = 'Alex Li'
3 from django.core.urlresolvers import resolve
4 from django.shortcuts import render,redirect
5
6 perm_dic = {
7 'view_customer_list': ['customer_list','GET',[]],
8 'view_customer_info': ['customer_detail','GET',[]],
9 'edit_own_customer_info': ['customer_detail','POST',['test']],
10 }
11
12 def perm_check(*args,**kwargs):
13 request = args[0]
14 url_resovle_obj = resolve(request.path_info)
15 current_url_namespace = url_resovle_obj.url_name
16 #app_name = url_resovle_obj.app_name #use this name later
17 print("url namespace:",current_url_namespace)
18 matched_flag = False # find matched perm item
19 matched_perm_key = None
20 if current_url_namespace is not None:#if didn't set the url namespace, permission doesn't work
21 print("find perm...")
22 for perm_key in perm_dic:
23 perm_val = perm_dic[perm_key]
24 if len(perm_val) == 3:#otherwise invalid perm data format
25 url_namespace,request_method,request_args = perm_val
26 print(url_namespace,current_url_namespace)
27 if url_namespace == current_url_namespace: #matched the url
28 if request.method == request_method:#matched request method
29 if not request_args:#if empty , pass
30 matched_flag = True
31 matched_perm_key = perm_key
32 print('mtched...')
33 break #no need looking for other perms
34 else:
35 for request_arg in request_args: #might has many args
36 request_method_func = getattr(request,request_method) #get or post mostly
37 #print("----->>>",request_method_func.get(request_arg))
38 if request_method_func.get(request_arg) is not None:
39 matched_flag = True # the arg in set in perm item must be provided in request data
40 else:
41 matched_flag = False
42 print("request arg [%s] not matched" % request_arg)
43 break #no need go further
44 if matched_flag == True: # means passed permission check ,no need check others
45 print("--passed permission check--")
46 matched_perm_key = perm_key
47 break
48
49 else:#permission doesn't work
50 return True
51
52 if matched_flag == True:
53 #pass permission check
54 perm_str = "crm.%s" %(matched_perm_key)
55 if request.user.has_perm(perm_str):
56 print("\033[42;1m--------passed permission check----\033[0m")
57 return True
58 else:
59 print("\033[41;1m ----- no permission ----\033[0m")
60 print(request.user,perm_str)
61 return False
62 else:
63 print("\033[41;1m ----- no matched permission ----\033[0m")
64 def check_permission(func):
65
66 def wrapper(*args,**kwargs):
67 print("---start check perms",args[0])
68 if not perm_check(*args,**kwargs):
69 return render(args[0],'crm/403.html')
70 return func(*args,**kwargs)
71 #print("---done check perms")
72 return wrapper
Middleware中间件
https://docs.djangoproject.com/es/1.9/topics/http/middleware/#process_request