Django 模板过滤器上的装饰器?
我有一个模板过滤器,它执行非常简单的任务并且运行良好,但我想在其上使用装饰器。不幸的是,装饰器导致了一个令人讨厌的 django 错误,没有任何意义...
有效的代码:
@register.filter(name="has_network")
def has_network(profile, network):
hasnetworkfunc = getattr(profile, "has_%s" % network)
return hasnetworkfunc()
使用装饰器(不起作用):
@register.filter(name="has_network")
@cache_function(30)
def has_network(profile, network):
hasnetworkfunc = getattr(profile, "has_%s" % network)
return hasnetworkfunc()
这是错误:
模板语法错误 /
渲染时捕获异常: 从空列表中弹出
我尝试在装饰器内设置断点,并且我有相当的信心它甚至没有被调用...
但以防万一这里是装饰器(我知道有人会要求它)
我(暂时)用一个什么也不做的模拟装饰器替换了装饰器,但我仍然得到相同的错误
def cache_function(cache_timeout):
def wrapper(fn):
def decorator(*args, **kwargs):
return fn(*args, **kwargs)
return decorator
return wrapper
编辑确认:这是因为装饰器需要*args
和 **kwargs
?我假设正在调用 pop()
来确保所有过滤器都至少接受一个参数?
将装饰器更改为此可以解决问题:
def cache_function(cache_timeout):
def wrapper(fn):
def decorator(arg1, arg2):
return fn(arg1, arg2)
return decorator
return wrapper
不幸的是,这破坏了装饰器的通用性质:/现在该怎么办?
I have a template filter that performs a very simple task and works well, but I would like to use a decorator on it. Unfortunately the decorator causes a nasty django error that doesn't make any sense...
Code that works:
@register.filter(name="has_network")
def has_network(profile, network):
hasnetworkfunc = getattr(profile, "has_%s" % network)
return hasnetworkfunc()
With Decorator (doesn't work):
@register.filter(name="has_network")
@cache_function(30)
def has_network(profile, network):
hasnetworkfunc = getattr(profile, "has_%s" % network)
return hasnetworkfunc()
Here is the error:
TemplateSyntaxError at /
Caught an exception while rendering:
pop from empty list
I have tried setting break points inside the decorator and I am reasonably confident that it is not even being called...
But just in case here is the decorator (I know someone will ask for it)
I replaced the decorator (temporarily) with a mock decorator that does nothing, but I still get the same error
def cache_function(cache_timeout):
def wrapper(fn):
def decorator(*args, **kwargs):
return fn(*args, **kwargs)
return decorator
return wrapper
edit CONFIRMED: It is caused because the decorator takes *args
and **kwargs
? I assume pop()
is being called to ensure filters all take at least one arg?
changing the decorator to this fixes the problem:
def cache_function(cache_timeout):
def wrapper(fn):
def decorator(arg1, arg2):
return fn(arg1, arg2)
return decorator
return wrapper
Unfortunately that ruins the generic nature of the decorator :/ what to do now?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最终答案:向装饰器添加一个额外的参数,指示正在装饰的内容
可能有更优雅的东西,但这是可行的。
Final Answer: Add an extra argument to the decorator indicating what is being decorated
There may be something more elegant, but this works.