[英]Handling a conditional block in a custom Django template tag
我有一个用作条件块的自定义 Django 模板标签:
{% if_has_permission request "some_permission" %}
<div>
<input type="text" name="sample_1">
<label><input type="checkbox" name="enable_it"> Enable</label>
</div>
{% endif_has_permission %}
在此示例中,如果请求对象没有适当的权限(在本例中为some_permission
),则不会呈现该块。 但是,一旦我将条件注入到这个块中(使用{% if %}
模板标记),我就会得到一个 TemplateSyntaxError:
{% if_has_permission request "some_permission" %}
<div>
<input type="text" name="sample_1">
<label><input type="checkbox" name="enable_it" {% if isChecked %}checked="checked"{% endif %}> Enable</label>
</div>
{% endif_has_permission %}
我看到的错误是:
无效的块标记:'endif',应为'endblock'
如果有的话,我可以做些什么来允许在我的自定义标签中使用条件表达式? 我很确定{% if %}
是我需要允许的唯一情况,尽管偶尔{% for %}
也可能有用。
这是我的自定义模板标记代码:
@register.tag
def if_has_permission(parser, token):
try:
args = token.split_contents()
tag_name, request, to_check = args[0], args[1], args[2]
opts = None
if(len(args) > 3):
opts = args[3:]
except IndexError:
raise template.TemplateSyntaxError("Tag %r requires at least two arguments" % tag_name)
if(not (to_check[0] == to_check[-1] and to_check[0] in ('"', "'"))):
raise template.TemplateSyntaxError("The second argument to tag %r must be in quotes" % tag_name)
nodelist_true = parser.parse(('endif_has_permission'),)
parser.delete_first_token()
return CheckPermissionNode(request, to_check[1:-1], opts, nodelist_true)
class CheckPermissionNode(template.Node):
def __init__(self, request, to_check, opts, nodelist_true):
self.request = template.Variable(request)
self.to_check = to_check
self.opts = opts
self.nodelist_true = nodelist_true
def render(self, context):
rq = self.request.resolve(context)
# Admins can always see everything
if(rq.session['is_admin']):
return self.nodelist_true.render(context)
# Check to see if any of the necessary permissions are present
hasPerm = False
checkList = self.to_check.split('|')
for c in checkList:
if(c in rq.session['perms']):
hasPerm = True
break
if(hasPerm):
return self.nodelist_true.render(context)
else:
return ''
模板标签不像块——把它们更像是方法。 您得到的错误是由于语法错误造成的。
要实现这样的东西,只需创建一个过滤器来检查条件(就像你的标签现在所做的一样)并返回True或False然后像这样使用它
{% if request|your_filter_name:"condition" %}
<p> do_sth </p>
{% endif %}
通过使用默认的 django-template if块
请注意,您不能在if块中使用标签 - 这就是为什么您需要将其更改为过滤器(通过添加register.filter
而不是register.tag
)。 除了语法,什么都不会改变:
request|your_filter:"condition"
代替
your_tag request "condition"
事实证明,这确实是可能的。 if_has_permission
例程中有一个错字:
nodelist_true = parser.parse(('endif_has_permission'),)
应该改为:
nodelist_true = parser.parse(('endif_has_permission',))
请注意,逗号在错误的位置! parse
函数需要一个元组。 修复这个错字可以防止事情出错。
顺便说一句,在遇到完全相同的问题后,我今天偶然发现了这个问题。 想象一下,大约五年前,当我发现自己是最初的提问者时,我的惊讶; 哈!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.