mydict = {"key1":"value1", "key2":"value2"}
在 Django 模板中查找字典值的常规方法是 {{ mydict.key1 }}
、{{ mydict.key2 }}
。如果键是循环变量怎么办? 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
失败。如何解决这个问题?
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 }}
在循环中从字典中获取键和值:
{% for key, value in mydict.items %}
{{ value }}
{% endfor %}
我发现这更容易阅读,并且避免了特殊编码的需要。无论如何,我通常需要循环内的键和值。
你不能默认。点是属性查找/键查找/切片的分隔符/触发器。
点在模板渲染中具有特殊的含义。变量名中的点表示查找。具体来说,当模板系统在变量名中遇到点时,它会按以下顺序尝试以下查找: 字典查找。示例: foo["bar"] 属性查找。示例: foo.bar 列表索引查找。示例: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 }}
return value.get(arg)
,因为如果密钥不存在,它不会引发 KeyError 异常。
对我来说,在我的应用程序中创建一个名为 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)
用法就像 culebrón 所说的:
{{ mydict|get_item:item.NAME }}
register = Library()
?它有什么作用 ?
django.template.base.Library
类下注册它。通过 register = Library()
我们实例化该类并在其中使用 filter
函数注释器来满足我们的需要。
我也有类似的情况。但是我使用了不同的解决方案。
在我的模型中,我创建了一个进行字典查找的属性。然后在模板中使用该属性。
在我的模型中: -
@property
def state_(self):
""" Return the text of the state rather than an integer """
return self.STATE[self.state]
在我的模板中: -
The state is: {{ item.state_ }}
环境:Django 2.2
示例代码:
from django.template.defaulttags import register
@register.filter(name='lookup')
def lookup(value, arg):
return value.get(arg)
我将此代码放在我的项目文件夹中的一个名为 template_filters.py 的文件中,该文件夹名为portfoliomgr
无论您将过滤器代码放在哪里,请确保该文件夹中有 __init__.py 将该文件添加到 projectfolder/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',
}
},
},
]
在您的 html 代码中加载库 {% load template_filters %}
由于我无法发表评论,让我以答案的形式这样做:
以 culebrón's answer 或 Yuji 'Tomita' Tomita's answer 为基础,传递给函数的字典是字符串形式,所以也许使用 { 3} 首先将字符串转换为字典,如 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 }}
环境: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>
{{ dict_obj.obj.obj_name }}
等同于 Python 代码 dict_obj["obj"]["obj_name"]
,但是,问题是关于 dict_obj[obj][obj_name]
的等价物。
不定期副业成功案例分享