如何将装饰器中带有参数的视图函数传递给django中的另一个装饰器

时间:2017-04-30 05:07:22

标签: python django view arguments decorator

我一直试图找到解决方案几个小时。我已经经历了很多SO posts,例如thisthisthis。我正在使用django-guardian在我的django应用程序中实现对象级权限。我正在尝试implement permission_required decorator dynamically。我们的想法是创建另一个装饰器,它可以在许可所需的装饰器之间切换,然后将视图函数传递给相应的permission_required装饰器。

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', Test.as_view()),
    url(r'(?P<handle>[-\w]+)/(?P<method>[-\w]+)/(?P<id>[-\w]+)/$', Test.as_view(), name='handler'),
]

Views.py

class Test(View):
    @decorator_switch
    def get(self, request, *args, **kwargs):
        return HttpResponse('Test View')

decorator_switch

from api.mappings.permission_mappings import perm_mappings

def decorator_switch(func):

def wrapper(instance, request, *args, **kwargs):
    print(kwargs)
    permission_decorator = \
        perm_mappings.get('handles').get(kwargs.get('handle')).get('actions').get(kwargs.get('method'))
    return permission_decorator(func)(request)(args)(kwargs)
return wrapper

permission_mappings

from django.contrib.auth.decorators import permission_required as django_perm_req
from api.decorators.guardian_perm_req import permission_required as guardian_perm_req
from pyteam.models import Team

perm_mappings = {
    'handles': {
        'team': {
            'actions':  {
                'get': guardian_perm_req('pyteam.retrieve_team', (Team, 'id', 'id')),
                'create': django_perm_req('pyteams.add_team', raise_exception=True),
                'update': guardian_perm_req('pyteam.change_team', (Team, 'id', 'id')),
                'delete': guardian_perm_req('pyteam.delete_team', (Team, 'id', 'id'))
                }
            }
        }
    }

在此之后我打开了网址http://localhost:8000/team/get/1/但是我得到了一个例外

  

/ team / get / 1 /

中的GuardianError      

参数id未传递到视图函数

我在kwargs中查看了kwargs的视图以及装饰器开关装饰器的kwargs,我找到了它。然后我检查了guardian_perm_req的包装函数,但def _wrapped_view(request, *args, **kwargs):的{​​{1}}没有得到导致此问题的url kwargs。

作为装饰器和基本功能,我尝试从装饰器开关本身调用并返回视图函数。

def decorator(view_func):

但正如预期的那样,点击劫持中间件会在此

上引发异常
  

/ team / get / 1 /

中的AttributeError      

'function'对象没有属性'get'

非常感谢任何帮助。

TIA

1 个答案:

答案 0 :(得分:1)

试试这个

return permission_decorator(func)(instance, request, *args, **kwargs)