[英]Django template how to look up a dictionary value with a variable
mydict = {"key1":"value1", "key2":"value2"}
The regular way to lookup a dictionary value in a Django template is {{ mydict.key1 }}
, {{ mydict.key2 }}
.在 Django 模板中查找字典值的常规方法是
{{ mydict.key1 }}
, {{ mydict.key2 }}
。 What if the key is a loop variable?如果键是循环变量怎么办? ie:
IE:
{% 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
fails. mydict.item.NAME
失败。 How to fix this?如何解决这个问题?
Write a custom template filter :编写自定义模板过滤器:
from django.template.defaulttags import register
...
@register.filter
def get_item(dictionary, key):
return dictionary.get(key)
(I use .get
so that if the key is absent, it returns none. If you do dictionary[key]
it will raise a KeyError
then.) (我使用
.get
以便如果键不存在,它不返回任何。如果你做dictionary[key]
它将引发一个KeyError
然后。)
usage:用法:
{{ mydict|get_item:item.NAME }}
Fetch both the key and the value from the dictionary in the loop:从循环中的字典中获取键和值:
{% for key, value in mydict.items %}
{{ value }}
{% endfor %}
I find this easier to read and it avoids the need for special coding.我发现这更容易阅读,并且避免了对特殊编码的需要。 I usually need the key and the value inside the loop anyway.
无论如何,我通常需要循环内的键和值。
You can't by default.你不能默认。 The dot is the separator / trigger for attribute lookup / key lookup / slice.
点是属性查找/键查找/切片的分隔符/触发器。
Dots have a special meaning in template rendering.
点在模板渲染中具有特殊意义。 A dot in a variable name signifies a lookup.
变量名中的点表示查找。 Specifically, when the template system encounters a dot in a variable name, it tries the following lookups, in this order:
具体来说,当模板系统遇到变量名中的点时,它会按以下顺序尝试以下查找:
- Dictionary lookup.
字典查找。 Example: foo["bar"]
示例:foo["bar"]
- Attribute lookup.
属性查找。 Example: foo.bar
示例:foo.bar
- List-index lookup.
列表索引查找。 Example: foo[bar]
示例:foo[bar]
But you can make a filter which lets you pass in an argument:但是您可以制作一个过滤器,让您传入一个参数:
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-filters 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 }}
For me creating a python file named template_filters.py
in my App with below content did the job对我来说,在我的应用程序中创建一个名为
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)
usage is like what culebrón said :用法就像 culebrón 所说的:
{{ mydict|get_item:item.NAME }}
I had a similar situation.我也有类似的情况。 However I used a different solution.
但是我使用了不同的解决方案。
In my model I create a property that does the dictionary lookup.在我的模型中,我创建了一个执行字典查找的属性。 In the template I then use the property.
在模板中,我然后使用该属性。
In my model: -在我的模型中:-
@property
def state_(self):
""" Return the text of the state rather than an integer """
return self.STATE[self.state]
In my template: -在我的模板中:-
The state is: {{ item.state_ }}
Since I can't comment, let me do this in the form of an answer:由于我无法发表评论,让我以答案的形式进行:
to build on culebrón's answer or Yuji 'Tomita' Tomita's answer , the dictionary passed into the function is in the form of a string, so perhaps use ast.literal_eval to convert the string to a dictionary first, like in this example .为了建立在culebrón 的答案或Yuji 'Tomita' Tomita 的答案的基础上,传递给函数的字典是字符串的形式,所以也许首先使用ast.literal_eval将字符串转换为字典,就像在这个例子中一样。
With this edit, the code should look like this:通过此编辑,代码应如下所示:
# 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 }}
Environment: Django 2.2环境:Django 2.2
from django.template.defaulttags import register
@register.filter(name='lookup')
def lookup(value, arg):
return value.get(arg)
I put this code in a file named template_filters.py in my project folder named portfoliomgr我将此代码放在名为portfoliomgr的项目文件夹中名为template_filters.py的文件中
No matter where you put your filter code, make sure you have __init__.py in that folder无论您将过滤器代码放在哪里,请确保该文件夹中有__init__.py
Add that file to libraries section in templates section in your projectfolder/settings.py file.将该文件添加到 projectfolder/settings.py 文件中模板部分的库部分。 For me, it is portfoliomgr/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',
}
},
},
]
In your html code load the library在您的 html 代码中加载库
{% load template_filters %}
env: django 2.1.7环境:django 2.1.7
view:看法:
dict_objs[query_obj.id] = {'obj': query_obj, 'tag': str_tag}
return render(request, 'obj.html', {'dict_objs': dict_objs})
template:模板:
{% 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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.