Django 与装饰器和正常功能相同的条件?

Django 与装饰器和正常功能相同的条件?,django,function,decorator,Django,Function,Decorator,我想根据正则表达式模式检查某个参数值,并且仅当它们匹配时才继续。这在我的应用程序中的很多地方都会发生,所以我决定让一个函数进行检查,并在需要时调用该函数。现在,在大多数情况下,我需要在视图的开头执行该检查,因此我将其创建为装饰器,如下所示: def validate(f): def _inner(request, argument=None): if argument is None: return HttpResponse(content="No

我想根据正则表达式模式检查某个参数值,并且仅当它们匹配时才继续。这在我的应用程序中的很多地方都会发生,所以我决定让一个函数进行检查,并在需要时调用该函数。现在,在大多数情况下,我需要在视图的开头执行该检查,因此我将其创建为装饰器,如下所示:

def validate(f):
    def _inner(request, argument=None):
        if argument is None:
            return HttpResponse(content="No argument given", status=400)
        elif not re.match('^SOME_REGEX$', argument):
            return HttpResponse(content="Invalid argument", status=400)
        else:
            return f(request, argument)
    return _inner

但在其他情况下,我需要从函数中调用该检查器,作为嵌套条件的一部分。似乎我不能直接调用它,例如,
validate(argument)
。有没有什么方法可以将相同的代码用作装饰器以及普通函数?或者我必须键入两次吗?

您当然不必键入两次,您只需创建一个
validate
函数,该函数接受一个值并对其进行验证:

def validate(argument):
    return re.match('^SOME_REGEX$', argument)
然后编写一个decorator,根据需要调用
validate
函数:

def requires_valid(f):
    def _inner(request, argument=None):
        if argument is None:
            return HttpResponse(content="No argument given", status=400)
        elif not validate(argument):
            return HttpResponse(content="Invalid argument", status=400)
        else:
            return f(request, argument)
    return _inner
显然,我不知道您的用例,因此您可能希望将对
None
的检查移动到
validate
中,但关键是,您不必重复相同的正则表达式两次

如果您想深入研究更深层的魔法,并坚持使用相同的函数作为装饰器和验证器,您可以尝试以下方法:

def validate(f):
    if callable(f):
        def _inner(request, argument=None):
            if argument is None:
                return HttpResponse(content="No argument given", status=400)
            elif not validate(argument):
                return HttpResponse(content="Invalid argument", status=400)
            else:
                return f(request, argument)
        return _inner
    else:
        return re.match('^SOME_REGEX$', f)

但我不建议这样做,因为根据参数的类型,有一个函数可以做两件非常不同的事情。这导致代码更难理解。(“你用这个函数来装饰一个视图,它接受一个字符串并返回bool?!”)

这个函数工作得很好,谢谢!我不知道
if callable()
——这似乎是一件非常实用的事情,我将对此进行研究。