Django模板如何使用变量查找字典值

thtygnil  于 2023-03-09  发布在  Go
关注(0)|答案(9)|浏览(182)
mydict = {"key1":"value1", "key2":"value2"}

在Django模板中查找字典值的常规方法是{{ mydict.key1 }}{{ mydict.key2 }}。如果键是一个循环变量呢?

{% for item in list %} # where item has an attribute NAME
  {{ mydict.item.NAME }} # I want to look up mydict[item.NAME]
{% endfor %}

mydict.item.NAME出现故障,如何修复?

kxxlusnw

kxxlusnw1#

编写自定义模板筛选器:

from django.template.defaulttags import register
...
@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

(我使用.get,这样如果键不存在,它就不会返回任何值。如果你使用dictionary[key],它就会产生一个KeyError。)
用法:

{{ mydict|get_item:item.NAME }}
y1aodyip

y1aodyip2#

在循环中从字典中同时获取键和值:

{% for key, value in mydict.items %}
    {{ value }}
{% endfor %}

我发现这更容易阅读,而且它避免了特殊编码的需要。无论如何,我通常需要循环内部的键和值。

tgabmvqs

tgabmvqs3#

默认情况下不能。点是属性查找/键查找/切片的分隔符/触发器。
点在模板呈现中具有特殊含义。变量名中的点表示查找。具体来说,当模板系统在变量名中遇到点时,它将按以下顺序尝试以下查找:

  • 字典查找。示例:foo[“酒吧”]
  • 属性查找。示例:foo.bar
  • 列表索引查找。示例:伏[巴]

但是你可以做一个过滤器,让你传入一个参数:
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-filters

@register.filter(name='lookup')
def lookup(value, arg):
    return value[arg]

{{ mydict|lookup:item.name }}
gxwragnw

gxwragnw4#

对于我来说,在我的应用程序中创建一个名为template_filters.py的python文件,并使用以下内容完成了这项工作

# coding=utf-8
from django.template.base import Library

register = Library()

@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

用法就像库莱布伦所说的:

{{ mydict|get_item:item.NAME }}
qncylg1j

qncylg1j5#

我也遇到过类似的情况,但我用了不同的解决方案。
在我的模型中,我创建了一个执行字典查找的属性,然后在模板中使用该属性。
在我的模型中:-

@property
def state_(self):
    """ Return the text of the state rather than an integer """
    return self.STATE[self.state]

在我的模板中:-

The state is: {{ item.state_ }}
70gysomp

70gysomp6#

环境: Django 2.2
1.示例代码:

from django.template.defaulttags import register

    @register.filter(name='lookup')
    def lookup(value, arg):
        return value.get(arg)

我将此代码放在名为portfoliomgr的项目文件夹中名为template_filters.py的文件中
1.无论您将过滤器代码放在何处,都要确保该文件夹中有**init.py**
1.将该文件添加到projectfolder/ www.example.com文件的模板部分的库部分settings.py。对我来说,它是portfoliomgr/settings.py

TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
                'libraries':{
                    'template_filters': 'portfoliomgr.template_filters',
                }
            },
        },
    ]

1.在html代码中加载库

{% load template_filters %}
pdsfdshx

pdsfdshx7#

既然我不能发表评论,让我以回答的形式来做这件事:
要在culebrón's answerYuji 'Tomita' Tomita's answer上构建,传入函数的字典是字符串形式的,因此可能要先使用ast.literal_eval将字符串转换为字典,就像this example中那样。
经过此编辑后,代码应如下所示:

# code for custom template tag
@register.filter(name='lookup')
def lookup(value, arg):
    value_dict = ast.literal_eval(value)
    return value_dict.get(arg)
<!--template tag (in the template)-->
{{ mydict|lookup:item.name }}
1cosmwyk

1cosmwyk8#

公认的答案很好用,但我只想添加如何使用过滤器链向下钻取嵌套值

mydict = {"USD": { "amount": 30 }, "JPY": { "amount": 3000 }}
currency = "JPY"
{{ mydict|get_item:currency|get_item:"amount" }}

输出将为3000

ebdffaop

ebdffaop9#

环境:Django 2.1.7
查看:

dict_objs[query_obj.id] = {'obj': query_obj, 'tag': str_tag}
return render(request, 'obj.html', {'dict_objs': dict_objs})

模板:

{% for obj_id,dict_obj in dict_objs.items %}
<td>{{ dict_obj.obj.obj_name }}</td>
<td style="display:none">{{ obj_id }}</td>
<td>{{ forloop.counter }}</td>
<td>{{ dict_obj.obj.update_timestamp|date:"Y-m-d H:i:s"}}</td>

相关问题