1

[编辑]所以看来我的代码工作正常,另一段代码+疲倦是问题[/编辑]。

我有一个装饰器,它可以简单地检查几个所需的请求键。

def fields_required(*fields):
assert isinstance(fields, tuple), "Fields must be of type tuple."

def wrap_func(fn):

    def wrapper(cls, request, *args, **kwargs):
        print 'oh hi'
        missing_fields = []
        for field in fields:
            if not request.REQUEST.has_key(field):
                missing_fields.append(field)

        if len(missing_fields) > 0:
            #maybe do smth here
            return HttpResponseBadRequest()          

        return fn(cls, request, *args, **kwargs)
    return wrapper
return wrap_func

如果其中一个字段丢失,我预计 HTTP 403 错误请求状态代码,但是装饰器从不执行该代码。

我的视图文件的基本表示:

class ViewA(View):

    @fields_required('name','api_key')
    def get(self, request, *args, **kwargs):
        # some logic

class ViewB(View):

    @fields_required('SHOULD_NEVER_SEE','THIS_STUFF')
    def get(self, request, *args, **kwargs):
        # some logic

在浏览器中打开 ViewA 时,控制台输出如下:

('name', 'api_key')
('SHOULD_NEVER_SEE','THIS_STUFF')

我不明白为什么要执行 ViewB 的装饰器,以及为什么我的控制台中没有“哦,嗨”。有什么见解吗?

4

1 回答 1

1

ViewB 的装饰器已“执行”,但不是因为您正在查看 ViewA。这是因为 Python 在执行文件本身时装饰了该方法。例如,b即使func未调用以下内容也会打印:

def deco(f):
    print 'b'
    def g():
        print 'c'
    return g

@deco
def func():
    print 'a'

关于不打印'oh hi'的问题;您可以尝试将装饰器添加到dispatch而不是get(即,将以下内容添加到您的视图中):

@method_decorator(fields_required('SHOULD_NEVER_SEE','THIS_STUFF'))
def dispatch(self, *args, **kwargs):
    pass
于 2012-04-04T14:40:37.830 回答