V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shinwood
V2EX  ›  Django

请教一个 Django 模板中用变量作为 key 取得 dict 值的问题。

  •  
  •   shinwood ·
    shinwood · 2013-04-24 00:08:03 +08:00 · 20832 次点击
    这是一个创建于 4262 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假设views.py有一个dict
    a = {'today':1, 'tomorrow':2, 'yesterday':3}

    在模板中,这样是无法得到值的,会显示空白:
    {% for k,v in a.items%}
    {{a.k}}
    {% endfor %}

    即对于k 的解析并不会视 key 为一个变量,而是视为一个字母k(非a.today 等),这部分有没有比较好的最佳实践解决办法?查了一下网上资料,有人说自己写一个filter,有人说换用Jinja2 或者Mako,但我觉得都比较麻烦,不像最佳方法。
    第 1 条附言  ·  2013-04-29 23:55:38 +08:00
    更新一下进度:

    最后还是用 template filter 解决的,可参考以下链接:

    https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
    17 条回复    2016-06-01 21:42:50 +08:00
    swulling
        1
    swulling  
       2013-04-24 00:17:40 +08:00
    访问字典不是 a[k]
    django 的template没用过,连这个也不允许么
    hzymyp
        2
    hzymyp  
       2013-04-24 01:33:06 +08:00   ❤️ 1
    {% endfor %}
    {% for k, v in time.items%}
    {{k}}
    {% endfor %}
    这样写是能得到的啊
    hzymyp
        3
    hzymyp  
       2013-04-24 01:39:35 +08:00   ❤️ 1
    忽略第一个endfor。。。
    shinwood
        4
    shinwood  
    OP
       2013-04-24 06:56:29 +08:00
    @swulling 不好意思,我举例可能有疏忽,我现实的场景是一个object,类似于这样
    a = {'today':<object1>, 'tomorrow':<object2>, 'yesterday':<object3>}

    然后用 v.val 之类的模板当中无法获得object 的属性值。


    @hzymyp 对,这样可以获得。我举例子中因为只有一个a,若是有一个b的dict的话,我要从a循环中得到b里面的值,就要用到 a.k 或者 a[k] (视a中元素的类型而定),这样子在模板中是无法得到值的,可以尝试一下看看。
    kidblg
        5
    kidblg  
       2013-04-24 10:04:50 +08:00   ❤️ 1
    swulling
        6
    swulling  
       2013-04-24 10:20:41 +08:00   ❤️ 1
    @shinwood 我想起来了,django的template比较严格,很久之前用过,很不爽。其实你可以考虑用其他的模版系统。比如Jinjia2
    yinian1992
        7
    yinian1992  
       2013-04-24 14:08:51 +08:00
    你都已经获得 value 了还要 key 取 value 干吗?
    shinwood
        8
    shinwood  
    OP
       2013-04-24 14:31:42 +08:00
    @yinian1992 设想我有两个dict:

    a = {'today':1, 'tomorrow':2, 'yesterday':3}
    b = {'today':1, 'yesterday':3}

    设想我要交叉一下

    for k,v in b.items():
    print a[k]

    类似于这种功能。
    yinian1992
        9
    yinian1992  
       2013-04-24 15:08:06 +08:00   ❤️ 1
    @shinwood 用 dot 必然是实现不了了
    看我的 O(n^2) 实现:

    {% for ak,av in a.iteritems %}
    {% for bk,bv in b.iteritems %}
    {% if ak == bk %}
    {{ bv }}
    {% endif %}
    {% endfor %}
    {% endfor %}
    shinwood
        10
    shinwood  
    OP
       2013-04-24 15:11:37 +08:00
    @yinian1992 233,这也可以!!感谢提供不错的思路,就是不知道如果量多的话效率如何?
    yinian1992
        11
    yinian1992  
       2013-04-24 15:13:47 +08:00
    @shinwood 一定效率捉急……
    ant_sz
        12
    ant_sz  
       2013-04-25 21:53:29 +08:00   ❤️ 1
    我再添一句
    像这样的功能原则上是应该放到 Controller 里的,不应该放到 View 里
    在Controller里建立一个 c 字典,然后用a的key把b的值取出来放到c里
    然后在模板里只引用c

    这样是比较符合MVC模式的实现方式
    shinwood
        13
    shinwood  
    OP
       2013-04-25 22:33:48 +08:00
    @ant_sz 原则上是如此,不过这样一来 view.py 当中的代码量就过于冗余了,django 模板的确失去了不少的灵活定制性。view 中可以不进行 db 操作,但我觉得像这样数组的操作还是很有必要的。
    davidzhang
        14
    davidzhang  
       2014-01-22 19:33:56 +08:00
    {% for k, v in time.items%}
    {{k}}
    {% endfor %}
    这样写是能得到的啊
    shinwood
        15
    shinwood  
    OP
       2014-01-22 20:29:17 +08:00
    @davidzhang 对,这是对于 time 这个对象当中的可以得到,如果我现在有一个 b 对象,我要得到 b.k 的值呢?
    HanSonJ
        16
    HanSonJ  
       2016-01-21 00:08:40 +08:00
    好久的贴,但想问问楼主的解决方案有没有案例?
    chrysan
        17
    chrysan  
       2016-06-01 21:42:50 +08:00
    @hzymyp 多年后还看到当初的解决方案,临时用一下。不过 tag 和 filter 的解决方案还是没有思路!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3710 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:13 · PVG 08:13 · LAX 16:13 · JFK 19:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.