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失败。如何解决这个问题?


当前回答

环境: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文件的templates部分的libraries部分。对我来说,它是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代码中加载库 {%加载template_filters %}

其他回答

环境: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文件的templates部分的libraries部分。对我来说,它是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代码中加载库 {%加载template_filters %}

我也遇到过类似的情况。然而,我使用了不同的解决方案。

在我的模型中,我创建了一个进行字典查找的属性。然后在模板中使用该属性。

在我的模型中:-

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

在我的模板:-

The state is: {{ item.state_ }}

因为我不能评论,让我以回答的形式来做这个: 基于culebrón的答案或Yuji 'Tomita' Tomita的答案,传递给函数的字典是字符串形式的,所以可以先使用ast.literal_eval将字符串转换为字典,如本例所示。

通过这样的编辑,代码应该是这样的:

# 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 }}

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

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

我发现这更容易阅读,并且避免了特殊编码的需要。我通常需要循环中的键和值。

env: 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>