首页 文章

Django:模板字典/对象交叉引用

提问于
浏览
1

在Django中,模板变量中的点理论上表示查找,基于以下分辨率顺序:

  • 字典查找 . 示例: foo["bar"]

  • 属性查找 . 示例: foo.bar

  • 方法调用 . 示例: foo.bar()

  • 列表索引查找 . 示例: foo[bar]

来自rendering a context in django 1.2(docs.djangoproject.com) .

事实上:

view

...
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")

template

Veggie by basket order, showing name

{% for veg in basket %}
    {{ veg }}
    {{ veggies.veg.name }}
{% endfor %}

output

Veggie by basket order, showing name

    a

    c

    b

该输出中没有素食名称 .

我认为这不是Django所说的那样 . 我很欣赏我可以写一个标签来解决这个问题 . 那很难看 .

根据Django ticket 12486,这对Django团队没有任何修复,因为"The intention is that Django's templates can be read and written by non-programmers, so complex logic should be view code or custom template tags."(Luke Plant)

我很感激在这种情况下写一些清晰的模板代码的实用建议(我有很多不同种类的“蔬菜”去引用) . 如果我们有模板编写者 - 哼 - 知道如何进行字典查找,是否值得离开Django?

3 回答

  • 1

    Django的模板引擎将for循环中的 veg 视为字符串,但是您尝试将其用作表达式的一部分 . 而Django 's template engine is an obstacle at times, what you are doing just doesn' t验证 . 你想要做的是获取 veggies 的属性,其名称包含在对象 veg 中,点符号不是't work that way either in Python or in Django'的模板 . 当你说veggies.veg时,它正在寻找名为 veg 的素食者的属性,而不是名为 a ,_1238383_或 c . 这不是很有意义的工作 .

    相反,只需将其吸取并编写模板标签以按名称访问任意对象的属性,或者将模板传递给模板中不需要这种逻辑的篮子 .

  • 2

    Django这样做的方法是准备用于在视图中呈现的数据结构(我认为这是为什么在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代码)对于模板逻辑来说过于复杂,并且有原因为了那个原因 . 我个人没有发现您的模板代码段非常易读,但这是个人喜好 .

    如果您不同意这种意识形态或者它限制了您的任务,那么很容易使用模板过滤器(无论如何都无法区分dct [var]和dct ['var']和dot-syntax,以及过滤器只是一个单行,没有任何收获在django本身)或者,如果这种意识形态真的很恶心,切换到不同的模板引擎,如jinja2 .

  • 0

    Django阻止你快速入侵模板来解决你的问题,因为它强制模板作者和视图作者之间的分离 . 想象一下,您销售了10,000种不同的蔬菜,并将它们保存在数据库表中 . 您是否真的想将所有10,000种蔬菜的字典传递到模板中以实现您所描述的内容?

    如果您使用真实模型而不是类和字典构建此示例,您可能已经拥有了所需的内容:"basket"将是一个具有"veggie"的外键引用的对象,以便 basket_item.veggie 将引用Veggie表中的行(呃,没有双关语意 . 您可以简单地传入篮子,当从模板引用时,素食项目将根据需要填充 . 为了提高效率,在获取篮子项目时,最终可能会使用 .select_related 来预先填充单个SQL查询中的素食项目 .

相关问题