장고 템플릿 변수로 사전 값을 찾는 방법


234
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실패합니다. 이 문제를 해결하는 방법?

답변:


362

사용자 정의 템플릿 필터를 작성하십시오.

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

(I 사용 .get하므로 키가 존재하지 않는 경우, 그것은 아무것도 반환하지 않습니다 것을. 당신이 경우에 dictionary[key]그것은을 올릴 것이다 KeyError다음.)

용법:

{{ mydict|get_item:item.NAME }}

16
장래에 이것을 찾을 사람들을위한 Django Custom Template Tag documentation .
Jeff

281
이것이 기본적으로 내장되어 있지 않은 이유는 무엇입니까? :-(
Berislav Lopac


5
Jinja2에서 {{mydict [key]}}
Evgeny

9
필터가 views.py, 추가 filters.py 또는 어떤 파일로 이동합니까?
AlanSE

56

루프의 사전에서 키와 값을 모두 가져옵니다.

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

나는 이것을 쉽게 읽을 수 있으며 특별한 코딩이 필요하지 않습니다. 어쨌든 일반적으로 루프 내부의 키와 값이 필요합니다.


28
그는 (당신이 보여주는대로) dict 열거를 요구하지 않았습니다-그는 변수 키가 주어지면 dict의 가치를 얻도록 요청했습니다. 귀하의 제안은 해결책을 제공하지 않습니다.
staggart

dict의 항목을 열거 한 다음 목록의 키와 일치시킬 수 있으므로 솔루션은 매우 비효율적입니다.
DylanYoung

1
액세스하려는 사전에 다른 사전이 포함되어 있으면이 기능이 작동하지 않습니다.
J0ANMM

값이 dict 인 경우 키와 값을 처리하기 위해 다른 for 루프를 포함 할 수 있지만 @culebron의 답변에 설명 된 것처럼 사용자 정의 필터를 사용하는 것이 복잡 할 수 있습니다.
Paul Whipp

37

기본적으로 할 수 없습니다. 점은 속성 조회 / 키 조회 / 슬라이스에 대한 구분자 / 트리거입니다.

점은 템플릿 렌더링에 특별한 의미가 있습니다. 변수 이름의 점은 조회를 나타냅니다. 특히 템플릿 시스템이 변수 이름에서 점을 발견하면 다음 순서로 다음 조회를 시도합니다.

  • 사전 검색. 예 : 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 }}

1
return value.get(arg)키가 없으면 KeyError 예외가 발생하지 않기 때문에 여전히 사용 합니다.
slajma

3

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()? 무엇을합니까?
MD. Khairul Basar

2
모든 템플릿에 새 필터에 대해 알리려면 django.template.base.Library클래스 아래에 등록해야합니다 . 에 의해 register = Library()우리는 그 클래스 및 사용의 인스턴스를 filter그 안에 함수 주석 자 우리의 필요에 도달한다.
AmiNadimi

2

나는 비슷한 상황을 겪었다. 그러나 다른 솔루션을 사용했습니다.

내 모델에서는 사전 조회를 수행하는 속성을 만듭니다. 그런 다음 템플릿에서 속성을 사용합니다.

내 모델에서 :-

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

내 템플릿에서 :-

The state is: {{ item.state_ }}

1

내가 말할 수 없기 때문에 대답의 형태로 이것을 할 수 있습니다 : culebrón 's answer 또는 Yuji ' Tomita'Tomita 's answer
기반으로 함수에 전달 된 사전은 문자열 형태이므로 ast를 사용하십시오 . literal_eval 에서와 같이, 먼저 사전에 문자열을 변환하는 .

이 편집을 통해 코드는 다음과 같아야합니다.

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

{{ mydict|lookup:item.name }}

0

환경 : 장고 2.2

  1. 예제 코드 :


    from django.template.defaulttags import register

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

이 코드를 templatemgr이라는 프로젝트 폴더의 template_filters.py 파일에 넣습니다.

  1. 필터 코드의 위치에 상관없이 해당 폴더에 __init__.py 가 있는지 확인하십시오

  2. 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',
                }
            },
        },
    ]
  1. html 코드에서 라이브러리를로드하십시오.

    
    {% load template_filters %}

-2

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

1
{{ dict_obj.obj.obj_name }}이 경우 템플릿 코드 는 Python 코드와 동일 dict_obj["obj"]["obj_name"]하지만 질문은에 해당합니다 dict_obj[obj][obj_name].
Flimm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.