我创建了一个中间件,它允许我使用字典列表为我的任何视图指定一些访问规则。这些字典中的每一个都如下所示:
REQUIREMENTS=(
{'viewname':'addtag',
'permissions':'can_add_tags'},
{'regex':re.compile(r'^somestart'),
'user_check':lambda request:request.user.username=='sam'}
)
然后,在我的中间件中,我尝试找出哪些要求与当前请求匹配。为此,我过滤了完整的 REQUIREMENTS,并在过滤器函数中使用此代码检查路径是否匹配:
def process_request(self,request):
def path_matches(self,req):
path_matches = False
if (req.has_key('url') and req['url'] == request.path ) or\
(req.has_key('regex') and req['regex'].search(request.path)) or\
(req.has_key('viewname') and resolve(request.path).url_name==req['viewname']):
path_matches=True
return path_matches
requirements = filter(path_matches,REQUIREMENTS)
# now use the returned requirements to determine if a user
# matches the requirement and
我现在的问题是:我应该按什么顺序使用支票?很明显,对 url 的检查是最快的,所以这必须是第一个。但接下来的问题是,是否应该首先遵循正则表达式搜索或 django 的 url 解析功能。
由于我现在没有任何性能问题,这更像是一个学术问题。如果有人有更好的解决方案来解决这个问题,那就更好了。
编辑:
为了对给定的答案做出反应:我想做的是创造一种可能性,将多个外部应用程序的视图限制在一个文件中。所以装饰器不是一种选择,只要我不想做这样的事情:
from ext_app1 import view1,view2
from ext_app2 import view3
@permission_required('can_do_stuff')
def view1_ext(*args,**kwargs):
return view1(args,kwargs)
这将导致每次我更改权限时都重写 url 规范。我想避免这种情况。此外,我的解决方案允许 user_check 函数对用户进行检查,如下所示:
def check_user(user):
if len(Item.objects.get(creator=user,datetime=today)) > 3:
return False
return True
这将是一种简单的方法,即限制用户每天可以上传多少项目。(好的,这也可以使用 user_passes_test )。
另一件事是,有时我只想在请求是 POST 或请求包含某个键:值对时才检查权限(比如'action':'delete'
应该需要权限,而'action':'change'
任何人都应该允许)。这也可以使用自定义装饰器来完成,但是一旦我需要新的检查,我就需要一个新的装饰器。