Django模板是否实现了逻辑表达式的短路?

时间:2016-06-28 20:13:43

标签: python django django-templates

假设我的Django模板中有以下内容:

Room_Id Status      Inspection_Date
4       vacant      3/25/2016
3       vacant      8/27/2015
3       vacant      12/12/2015
3       vacant      3/22/2016
4       occupied    2/2/2015
4       vacant      3/24/2015

如果{% if a != None and a.b > 5 %} 为无,我可以确定a.b > 5不会被评估吗?

IE:在评估Django模板中的逻辑表达式时,python是否会短路?

2 个答案:

答案 0 :(得分:3)

是的,它会短路。我已经看了Django 1.9.2的来源,并认为我找到了the relevant code

# Operator precedence follows Python.
# NB - we can get slightly more accurate syntax error messages by not using the
# same object for '==' and '='.
# We defer variable evaluation to the lambda to ensure that terms are
# lazily evaluated using Python's boolean parsing logic.
OPERATORS = {
    'or': infix(6, lambda context, x, y: x.eval(context) or y.eval(context)),
    'and': infix(7, lambda context, x, y: x.eval(context) and y.eval(context)),
    'not': prefix(8, lambda context, x: not x.eval(context)),
    'in': infix(9, lambda context, x, y: x.eval(context) in y.eval(context)),
    'not in': infix(9, lambda context, x, y: x.eval(context) not in y.eval(context)),
    # This should be removed in Django 1.10:
    '=': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)),
    '==': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)),
    '!=': infix(10, lambda context, x, y: x.eval(context) != y.eval(context)),
    '>': infix(10, lambda context, x, y: x.eval(context) > y.eval(context)),
    '>=': infix(10, lambda context, x, y: x.eval(context) >= y.eval(context)),
    '<': infix(10, lambda context, x, y: x.eval(context) < y.eval(context)),
    '<=': infix(10, lambda context, x, y: x.eval(context) <= y.eval(context)),
}

IfParser 类用于评估if块表达式中的条件。在上面,它被视为使用内置的and功能。

证明这一点的一个例子可能使用如下视图:

def printer(): print 'called'

class IndexView(TemplateView):
    template_name = 'index.html'
    def get(self, request, *args, **kwargs):
        return self.render_to_response({'log': printer})

以下模板将会打印并且不会打印&#34;称为&#34;分别到控制台。

{% if True and log %}  # prints "called"
{% if False and log %} # does not print "called"

答案 1 :(得分:1)

这种行为似乎没有在官方文档中指定,但bug #13373的存在意味着他们这样做,除了在v1.2 beta中。

commit fef0d25bdc中的修正似乎仍然出现在smartif.py的{​​{3}}中,因此假设它仍然可以正常运行。