python - Django的模板语言不能安全的处理dict

标签 python django django-templates

在django的模板语言中,如果一个变量名为a.x,那么django会按照这个顺序尝试获取正确的值:

  1. a['x'], 字典查找
  2. a.xa.x(),属性或方法查找
  3. a[x],列表索引

结果是:任何支持 var['str'] 的变量都变成了定时炸弹。假设 a 是一个 dict,具有值为 'hello world' 的键 'items',那么 a.items 将导致 'hello world',而不是 ditc.items()。这是代码:

from django.template import Engine, Context
template = """
{% for k, v in a.items %}
{{ k }} = {{ v }}
{% endfor %}
"""

e = Engine()
t = e.from_string(template)
a = {'items': 'hello world'}
print(t.render(Context({'a': a})))

虽然我期望 items = hello world 作为输出,但实际输出是:

h = 

e = 

l = 
...

对于字典变量,如果它有一个与字典方法同名的键,那么你将永远无法在模板中调用该方法。它变成了一颗定时炸弹,因为您永远不知道将来是否会在字典变量中添加一个名为“items”的键。

这种风险不仅存在于 dict,还存在于任何接受 var['key'] 的类型。

所以我的问题是,为什么订单是这样设计的,如何保证安全。

最佳答案

有一个简单的解决方法(除了为您的 key 使用更好的名称之外):

from django.template import Engine, Context

template = """
{% for k, v in items_func %}
{{ k }} = {{ v }}
{% endfor %}
"""

e = Engine()
t = e.from_string(template)
a = {'items': 'hello world'}
print(t.render(Context({'a': a, 'items_func': a.items})))
>> items = hello world

关于python - Django的模板语言不能安全的处理dict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37159602/

相关文章:

python - 开发Django项目时Docker是否可以替代 'virtualenv'?

mysql - AWS RDS中将sqlite3从Django迁移到mysql总是报语法错误

django - 如何在 Django 1.8 的 render_to_response 中使用 RequestContexts

django - 从查询集中获取唯一多对多记录的列表

python - JSON 内容中的幻像换行符

python - Golang的TLE(超过时间限制)错误,但使用类似逻辑的Python则没有。但为什么?

django - 在 MVC(例如 Django)中,放置繁重逻辑的最佳位置是什么?

python - 用最后一个非零值填充 1d numpy 数组的零值

python - 无法安装python ast

django - 从 Django 模板中删除换行符