Как получить доступ к элементу словаря в шаблоне Django?

Я хотел бы распечатать количество голосов, которые получил каждый выбор. У меня есть этот код в шаблоне:

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

votes - это просто словарь, а choices - это модельный объект.

Это вызывает исключение с этим сообщением:

"Could not parse the remainder"

Ответ 1

Чтобы повторить/распространить на комментарий Джеффа, я думаю, что вам следует стремиться, это просто свойство в вашем классе 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 состоит в том, чтобы изолировать вас от кода в ваших шаблонах и наоборот.

Я бы попробовал вышеуказанный метод и посмотрел, какой SQL генерирует ORM, поскольку я не уверен, что он будет предварительно кэшировать свойства и просто создать подзапрос для этого свойства или если он будет итеративно /on -demand запускает запрос для подсчета количества голосов. Но если он генерирует жестокие запросы, вы всегда можете заполнить свойство в своем представлении данными, которые вы собрали сами.

Ответ 2

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

Вот шаблон:

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

По сути, .items - это ключевое слово Django, которое разбивает словарь на список пар (key, value), очень похоже на метод Python .items(). Это позволяет выполнять итерацию по словарю в шаблоне Django.

Ответ 3

вы можете использовать точечную нотацию:

Точные поиски можно суммировать как это: когда шаблонная система встречает точку в имени переменной, он пробует следующие поиски, в этот порядок:

  • Поиск словаря (например, foo [ "bar" ])
  • Поиск атрибутов (например, foo.bar)
  • Вызов метода (например, foo.bar())
  • Поиск по списку-индексу (например, foo [2])

Система использует первый тип поиска это работает. Его логика короткого замыкания.

Ответ 4

Вам нужно найти (или определить) тег шаблона "get", например, здесь.

Определение тега:

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

И его использовали как:

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

Ответ 5

Используйте элементы словаря

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

Ответ 6

django_template_filter имя фильтра get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

Ответ 7

Аналогично ответу @russian_spy:

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

Это может быть полезно для разбивки более сложных словарей.

Ответ 8

В идеале вы должны создать метод на объекте выбора, который попадает в число голосов, или создать связь между моделями. Тег шаблона, который выполнил поиск словаря, тоже будет работать.