2017-10-07 230 views
0

我想从Jinja2模板中获取所有未定义的变量。 假设我有一个如下所示的模板。如何从Jinja2模板中获取所有未定义的变量?

tmpstr = """ 
{% for row in csv %} 
sample {{row.field1}} stuff {{row.field2}} morestuff {{row.field3}} 
{% endfor %} 
""" 

和输入字典如下

cxt = {'csv': [ 
    {'field3': 1234, 'field4': 12314}, 
    {'field3': 2222, 'field4': 1213} 
]} 

这里是我尝试呈现它。

env = Environment(undefined=Undefined) 
tmp = env.from_string(tmpstr) 
tmpsrc = tmp.render(cxt) 
print(tmpsrc) 

模板期望变量field1,field2和field3存在。但是字段1字段2不存在。我的目标是找到所有缺失的变量。

Jinja2很少忽略缺少的变量。因此,我试图添加StrictUndefined选项。

errs = [] 
try: 
    env = Environment(undefined=StrictUndefined) 
    tmp = env.from_string(tmpstr) 
    tmpsrc = tmp.render(cxt) 
except Exception as e: 
    errs.append(str(e)) 
print(errs) 

然而此时的Jinja2只能抱怨第一缺失变量这是FIELD1

因此我想另一种选择是DebugUndefined 此选项不会产生异常,因此只有在模板输出替换缺失变量。因此我不能收集缺失的变量。

你能建议我怎么能在jinja2模板中缺少变量?

这里是可运行的代码,如果有人想尝试一下

from jinja2 import BaseLoader,Environment,StrictUndefined,DebugUndefined,Undefined 
tmpstr = """ 
{% for row in csv %} 
sample {{row.field1}} stuff {{row.field2}} morestuff {{row.field3}} 
{% endfor %} 
""" 
cxt = {'csv': [ 
    {'field3': 1234, 'field4': 12314}, 
    {'field3': 2222, 'field4': 1213} 
]} 
env = Environment(undefined=Undefined) 
tmp = env.from_string(tmpstr) 
tmpsrc = tmp.render(cxt) 
print('CASE 1: undefined=Undefined') 
print(tmpsrc) 

errs = [] 
try: 
    env = Environment(undefined=StrictUndefined) 
    tmp = env.from_string(tmpstr) 
    tmpsrc = tmp.render(cxt) 
except Exception as e: 
    errs.append(str(e)) 
print('CASE 2: undefined=StrictUndefined') 
print(errs) 

errs = [] 
try: 
    env = Environment(undefined=DebugUndefined) 
    tmp = env.from_string(tmpstr) 
    tmpsrc = tmp.render(cxt) 
except Exception as e: 
    errs.append(str(e)) 

print('CASE 3: undefined=DebugUndefined') 
print(errs) 
print(tmpsrc) 

回答

2

我找到了解决您的问题,使用jinja2.make_logging_undefined。我和你在同一条船上,一直在寻找答案。大多数答案指出我使用解析模板,但我无法弄清楚如何将上下文放入解析模板中。

我终于可以使用make_logging_undefined进行这项工作。如果您想查找所有未定义的变量,请确保仅使用Undefined基类,而不是StrictUndefined。使用StrictUndefined会导致jinja在第一次遇到undefine时抛出异常。

只是一个免责声明:我不是一个python也不是jinja专家,所以代码不是最有效也不是结构化的。但它符合我的目的。这只是POC代码。

下面的代码:

import jinja2 
import logging 
from jinja2 import Environment, Undefined 
from jinja2.exceptions import UndefinedError 

def main(): 
    templateLoader = jinja2.FileSystemLoader(searchpath="D:\\somelocation\\") 

    logging.basicConfig() 
    logger = logging.getLogger('logger') 
    LoggingUndefined = jinja2.make_logging_undefined(logger=logger,base=jinja2.Undefined) 

    templateEnv = jinja2.Environment(loader=templateLoader, undefined=LoggingUndefined) 

    TEMPLATE_FILE = "./example1.jinja" 

    template = templateEnv.get_template(TEMPLATE_FILE) 

    FAVORITES = [ "chocolates", "lunar eclipses", "rabbits" ] 
    # Specify any input variables to the template as a dictionary. 
    templateVars = { "title" : "Test Example", 
        "description" : "A simple inquiry of function.", 
        "favorites" : FAVORITES, 
        "whatever" : "1" 
        }  
    # Finally, process the template to produce our final text. 
    try: 
     outputText = template.render(templateVars) 
    except (UndefinedError) as err: 
     print err 

if __name__ == '__main__': 
    main() 

example1.jinja:

<!doctype html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" /> 

    <title>{{ title }}</title> 
    <meta name="description" content="{{ description }}" /> 
</head> 

<body> 

<div id="content"> 
    <p>Greetings visitor! These are a list of my favorite things:</p> 

    <ul> 
    {% for item in favorites %} 
    <li>{{ item }}</li> 

    <li>My favorites: {{ favorites[1] }} </li> 
    {% endfor %} 
    {{ undefined_var1 }} 
    {{ underfined_var2 }} 
    </ul> 
</div> 

</body> 
</html> 

这里的示例输出:

WARNING:logger:Template variable warning: undefined_var1 is undefined 
WARNING:logger:Template variable warning: underfined_var2 is undefined 
+0

我已经最终使用** ** DebugUndefined和使用正则表达式'{{(。*?)}}'查找渲染模板中的缺失变量。然而,我会upvote为您的答案,因为它使用日志记录。谢谢。 – moth

+0

感谢您的支持。使用make_logging_undefined的输出在示例中都是未定义的变量。以下是输出示例:警告:记录器:模板变量警告:undefined_var1未定义# 警告:记录器:模板变量警告:underfined_var2未定义 – Balitong