代码之家  ›  专栏  ›  技术社区  ›  J.J.

Django模板中的嵌套点查找

  •  6
  • J.J.  · 技术社区  · 15 年前

    根据 The Django Book ,Django的模板系统支持嵌套点查找:

    点查找可以嵌套多层深度。例如,下面的示例使用person.name.upper,它转换为字典查找(person['name']),然后使用方法调用(upper()):'person.name.upper is person.age years old.。

    文档中是否有这种方法未被广泛涵盖的地精?我遇到了嵌套点查找的问题--下面是一个最小的示例:

    查看:

    test = [{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}]
    ndx = 'bar'
    t = loader.get_template('meh.html')
    c = Context({'test': test,
                 'ndx': ndx,})
    return HttpResponse(t.render(c))
    

    meh.html模板:

    <pre>
       {{ test }}
       {{ test.0 }}
       {{ test.0.ndx }}
    </pre>
    

    结果HTML:

    <pre>
    [{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}]
     {'foo': [1, 2, 3], 'bar': [4, 5, 6]}
    
    </pre>
    

    当我期望[4,5,6]时,对list元素中字典键的嵌套查找不会返回任何结果。

    J·J

    4 回复  |  直到 15 年前
        1
  •  8
  •   David Berger    15 年前

    我想问题是你在期待 ndx 当那根本不可能发生的时候被评估。您是否尝试过:

    {{ test.0.bar }}
    

    我想这会满足你的要求。

    有没有这种方法的妖精…?

    有点,但他们不是你说的,我不认为是因为筑巢,或者至少, 当你达到一级深度后,情况不会变得更糟。 . 我的意思是,所有的查找参数都是文本。这是无法改变的。因此,虽然您可能能够开发自定义模板标记并将其传递给文本或变量进行评估,但如果您希望根据另一个值的评估值直接访问某个变量的某个成员,那么就真是走运了。(您可以为此编写一个模板标记,但它不能在所有需要的情况下工作,而且可能比它的价值更复杂。)

    不管它有什么价值,这看起来像是模板语言的一个非常有意的方面。我邀请你考虑一下访问者应该如何知道 {{ foo.bar }} 应该读作 foo[bar] foo['bar'] . 在不使语法复杂化的情况下做出有意义的判断似乎是不可能的,而这正是Django的模板设计所坚持避免的。

        2
  •  4
  •   Will McCutchen    15 年前

    为了扩展大卫的答案,Django的模板系统不允许您使用上下文变量的值作为键。所以,在你的例子中

    {{ test.0.ndx }}
    

    实际上是在找钥匙 "ndx" 在第一项中 test 上下文变量。

    如果您需要这个功能,您需要自己实现它,作为一个模板过滤器。 This ticket 有更多的信息,包括django-devs在省略这个特性背后的推理,以及您正在寻找的模板过滤器的示例实现。

        3
  •  1
  •   Ned Batchelder    15 年前

    戴维是对的: ndx 不会被评估为获得一个密钥,它将被字面上用作一个密钥。您可以定义一个新的模板标记来执行您想要的操作,下面是一个简单的标记: http://www.djangosnippets.org/snippets/1412/

        4
  •  1
  •   dagoof    15 年前

    我建议(我同意大卫对你问题的解释):

    {{ test.0.bar }} # as david mentioned, or
    
    ndx=test[0]['bar'] # in views
    {{ ndx }} # in template