在Django中,模板变量中的点在理论上表示基于以下分辨率的查找:
foo["bar"]
foo.bar
foo.bar()
foo[bar]
来自在django 1.2中呈现上下文 (docs.djangoproject.com)。
在现实中:
视图
...
class Veggie(object):
def __init__(self, name):
self.name = name
veggies = {'a': Veggie('carrot'), 'b': Veggie('lettuce')}
basket = ['a', 'c', 'b']
return render_to_response('tpls/veggies.txt',
{'veggies': veggies, 'basket': basket},
mimetype="text/plain")
模板
Veggie by basket order, showing name
{% for veg in basket %}
{{ veg }}
{{ veggies.veg.name }}
{% endfor %}
输出
Veggie by basket order, showing name
a
c
b
输出中没有素食主义者的名字。
我想这不是Django说的。我很感激我可以,一个la Peter Harkins "Django字典访问模板标签“,写一个标签来解决这个问题。太丑了。
按照姜戈票12486的说法,这对Django团队来说是一个否定的解决方案,因为“目的是让非程序员可以读写Django的模板,所以复杂的逻辑应该是查看代码或自定义模板标记。”(路克植物)
对于在这种情况下编写可阅读的模板代码,我将非常感激(我有很多不同种类的“蔬菜”要删除)。如果我们有模板作者知道如何进行字典查找,那么离开Django值得吗?
发布于 2011-08-07 13:43:04
Django的模板引擎将for循环中的veg
作为字符串处理,但您正在尝试将其用作表达式的一部分。尽管Django的模板引擎有时是一个障碍,但您所做的只是无法验证。您想要做的是获取veggies
的属性,其名称包含在对象veg
中,而点表示法在veg
或Django的模板中都不能这样工作。当您说veggies.veg时,它是在蔬菜上寻找一个名为veg
的属性,而不是a
、b
或c
。这不是Django模板引擎的缺陷;这正是Python (以及我所知道的每一种语言)的工作方式。
相反,只需吸收它并编写一个模板标记来访问任意对象的属性(按名称),或者传递模板--一个不需要模板中的逻辑的篮子。
发布于 2011-08-07 13:48:10
这样做的方法是准备在视图中呈现的数据结构(我认为这是为什么Django中的" view“称为"view”的原因之一)。
basket = [veggies[veg_id] for veg_id in basket_id_list]
然后
{% for veg in basket %}
{{ veg.name }}
{% endfor %}
所以,通过你想要渲染的结构,而不是你得到的结构。django并不认为模板编写人员无法理解字典查找(或者是一些python代码),django认为变量字典查找(以及任意python代码)对于模板逻辑来说太复杂了,这是有原因的。我个人认为你的模板代码片段不太容易读,但这是个人偏好。
如果您不同意这种思想,或者它限制了您的任务,那么就很容易使用模板过滤器(无论如何都无法区分带有点语法的dctvar和dct‘’var‘,而且过滤器只是一行,在django本身中使用它是没有好处的),或者,如果这种思想非常恶心,就切换到另一个模板引擎,比如jinja2。
发布于 2011-08-07 12:06:28
Django阻止您在模板中快速攻击以解决您的问题,因为它强制模板作者和视图作者之间进行分离。假设您出售了10,000种不同的蔬菜,并将它们保存在数据库表中。你真的想把一本所有10,000种蔬菜的字典传递到模板中来启用你描述的内容吗?
如果您使用实际的模型而不是类和字典来构建这个示例,那么您可能已经得到了您想要的东西:“购物篮”将是一个带有外键引用" Veggie“的对象,因此basket_item.veggie
将引用Veggie表中的一行(嗯,不打算使用双关语)。您可以简单地传递到篮中,当从模板引用时,将根据需要填充素食项。为了提高效率,您最终可能会在获取购物篮项以在单个SQL查询中预先填充素食项时使用.select_related
。
https://stackoverflow.com/questions/6975359
复制相似问题