Django 템플릿에서 사전 요소에 액세스하는 방법은 무엇입니까?


181

각 선택의 투표 수를 인쇄하고 싶습니다. 이 코드는 템플릿에 있습니다.

{% for choice in choices %}
    {{choice.choice}} - {{votes[choice.id]}} <br />
{% endfor %}

voteschoices모델 객체 인 반면 사전 입니다.

이 메시지와 함께 예외가 발생합니다.

"Could not parse the remainder"

답변:


63

Jeff의 의견을 반영 / 확장하기 위해 내가 목표로 삼아야 할 것은 단순히 해당 객체와 관련된 투표 수를 계산하는 Choice 클래스의 속성입니다.

class Choice(models.Model):
    text = models.CharField(max_length=200)

    def calculateVotes(self):
        return Vote.objects.filter(choice=self).count()

    votes = property(calculateVotes)

그런 다음 템플릿에서 다음을 수행 할 수 있습니다.

{% for choice in choices %}
    {{choice.choice}} - {{choice.votes}} <br />
{% endfor %}

템플릿 태그는 IMHO 가이 솔루션에 약간 과잉이지만, 끔찍한 해결책도 아닙니다. Django에서 템플릿의 목표는 템플릿의 코드로부터 사용자를 격리시키는 것입니다.

위의 방법을 시도하고 속성을 사전 캐시하고 속성에 대한 하위 선택을 만들거나 반복적으로 / on- 요청은 투표 수를 계산하기 위해 쿼리를 실행합니다. 그러나 끔찍한 쿼리를 생성하는 경우 언제든지 수집 한 데이터로보기의 속성을 채울 수 있습니다.


@ john ewart에게 감사드립니다. 솔루션이 나를 위해 일했습니다. 나는 django와 python의 초보자이며 ORM이 생성 한 SQL을 얻는 방법을 알 수 없습니다.
Mohamed

docs.djangoproject.com/en/dev/faq/models/… 이 비트에 대한 답을 찾을 수 있습니다. 실제로 매우 간단하고 실제로 템플릿에 표시되거나 로깅 기능으로 기록 될 수 있지만 이것이 작동하려면 DEBUG를 켜야합니다.
John Ewart

이 솔루션은 django templating + Google 앱 엔진 모델과 관련된 문제에 완벽합니다. 두 번 투표 할 수 있으면 좋겠습니다.
Conrad.Dean

5
작동하지만 매우 효율적이지 않습니다. 루프에서 SQL 쿼리를 수행하고 있습니다 (피해야 할 것). dict 조회를 수행하기위한 고유 한 태그 작성은 쉽습니다. @ register.filter def lookup (d, key) : if d and isinstance (d, dict) : return d.get (key)
dalore

클래스를 만드는 것은 너무 많은 오버 헤드입니다. 더 나은 구조화 된 사전 .items은 다른 답변들 중 하나에서 설명 된 것처럼 호출 과 결합되어 훨씬 간단한 솔루션입니다.
Zags

285
choices = {'key1':'val1', 'key2':'val2'}

템플릿은 다음과 같습니다.

<ul>
{% for key, value in choices.items %} 
  <li>{{key}} - {{value}}</li>
{% endfor %}
</ul>

기본적으로 Python 메소드와 매우 유사하게 .items사전을 (key, value)쌍 목록으로 나누는 Django 키워드입니다 .items(). 이를 통해 Django 템플릿에서 사전을 반복 할 수 있습니다.


@anacarolinats (및 기타)는 choices.items의 핵심 가치를 반복적으로 확인합니다. 여전히 작동합니다.
OldTinfoil

드디어! 감사합니다!! : D
djGrill

템플릿 엔진에서는 ()를 사용할 수 없습니다. BTW 감사합니다.
BlaShadow

6
질문에 대한 간결한 해결책. 명확히하기 위해 itemsDjango 키워드가 아닌 사전에 대한 Python 메소드 호출입니다. 으로 알렉스 마르 텔리는 지적 은 기본적으로 동일합니다 iteritems. Wilhelm이 대답했듯이 사전 조회는 도트 조회에서 3 위입니다. 사전에이라는 이름의 항목이 있으면 'items'튜플 목록 대신 해당 값을 가져옵니다. 테스트하려면 : {'items':'oops'}사전에 추가 하면 단어 'oops'에서 글 머리 기호 목록이 표시됩니다.
cod3monk3y

1
collections.OrderedDict를 사용하여 반복 순서를 제어하십시오
dnalow

186

점 표기법을 사용할 수 있습니다.

도트 룩업은 다음과 같이 요약 될 수 있습니다. 템플릿 시스템이 변수 이름에서 도트를 발견하면 다음 순서로 다음 룩업을 시도합니다.

  • 사전 조회 (예 : foo [ "bar"])
  • 속성 조회 (예 : foo.bar)
  • 메소드 호출 (예 : foo.bar ())
  • 목록 인덱스 조회 (예 : foo [2])

시스템은 작동하는 첫 번째 조회 유형을 사용합니다. 단락 논리입니다.


44
그의 경우 선택은 변수입니다. .choice를 수행하면 키 "choice"의 값 대신 키 선택의 값이 검색됩니다.
ibz

질문이 "내가 생각하는 것을 추측"하는 질문이지만 정보에 +1합니다. 고마워 빌헬름
eficker

1
이것은 심지어 중첩 된 사전에서도 작동합니다. 파이썬 코드 : my_dict[1][2]템플릿 코드 :my_dict.1.2
djsmith

2
@ JCLeitão 올바른 버전이기 때문에 d.key.1-두 번째 참고.
Izkata

3
"1.6 docs.djangoproject.com/en/1.6/topics/templates/#variables " 에서 문서를 확인하십시오. {{foo.bar}}와 같은 템플릿 표현식의 "bar"는 해석됩니다. 템플릿 컨텍스트에 변수 "bar"가있는 경우 리터럴 문자열로 사용합니다.
jamesc

25

'get'템플릿 태그를 찾거나 정의해야합니다 (예 : here) .

태그 정의 :

@register.filter
def hash(h, key):
    return h[key]

그리고 그것은 다음과 같이 사용됩니다 :

{% for o in objects %}
  <li>{{ dictionary|hash:o.id }}</li>
{% endfor %}

3
h.get(key,'default_value')KeyError 때문에 고려
semiomant

9

사전 항목 사용 :

{% for key, value in my_dictionay.items %}
  <li>{{ key }} : {{ value }}</li>
{% endfor %}


6

@russian_spy의 답변과 유사합니다.

<ul>
{% for choice in choices.items %} 
  <li>{{choice.0}} - {{choice.1}}</li>
{% endfor %}
</ul>

보다 복잡한 사전을 분류하는 데 적합 할 수 있습니다.


3

이상적으로는 투표에서 찾은 선택 객체에 대한 메소드를 작성하거나 모델 간의 관계를 작성하는 것이 이상적입니다. 사전 조회를 수행 한 템플릿 태그도 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.