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

How to pass a view function with arguments in a decorator to another decorator in django

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

urls.py

1
2
3
4
5
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

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

decorator_switch

1
2
3
4
5
6
7
8
9
10
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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'))
                }
            }
        }
    }

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

GuardianError at /team/get/1/

Argument id was not passed into view function

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

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

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

但正如预期的那样,点击劫持中间件引发了一个例外

AttributeError at /team/get/1/

'function' object has no attribute 'get'

任何帮助是极大的赞赏。

TIA


试试这个

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