如何在Django模板中访问字典元素?

问题:如何在Django模板中访问字典元素?

我想打印出每个选择获得的票数。我在模板中有以下代码:

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

votes只是一个字典,而choices只是一个模型对象。

该消息引发异常:

"Could not parse the remainder"

I would like to print out the number of votes that each choice got. I have this code in a template:

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

votes is just a dictionary while choices is a model object.

It raises an exception with this message:

"Could not parse the remainder"

回答 0

为了回应/扩展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 %}

模板标签,恕我直言,此解决方案有些过分,但也不是一个糟糕的解决方案。Django中模板的目标是使您与模板中的代码隔离,反之亦然。

我会尝试上述方法,并查看ORM生成的SQL,因为我不确定它是否会预先缓存属性并仅为该属性创建子选择,还是会迭代/启用-需求运行查询以计算投票数。但是,如果它产生了残酷的查询,您总是可以使用自己收集的数据填充视图中的属性。

To echo / extend upon Jeff’s comment, what I think you should aim for is simply a property in your Choice class that calculates the number of votes associated with that object:

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

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

    votes = property(calculateVotes)

And then in your template, you can do:

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

The template tag, is IMHO a bit overkill for this solution, but it’s not a terrible solution either. The goal of templates in Django is to insulate you from code in your templates and vice-versa.

I’d try the above method and see what SQL the ORM generates as I’m not sure off the top of my head if it will pre-cache the properties and just create a subselect for the property or if it will iteratively / on-demand run the query to calculate vote count. But if it generates atrocious queries, you could always populate the property in your view with data you’ve collected yourself.


回答 1

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模板中的字典上进行迭代。

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

Here’s the template:

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

Basically, .items is a Django keyword that splits a dictionary into a list of (key, value) pairs, much like the Python method .items(). This enables iteration over a dictionary in a Django template.


回答 2

您可以使用点符号:

点查找可以总结如下:当模板系统遇到变量名称中的点时,它将按以下顺序尝试以下查找:

  • 字典查询(例如foo [“ bar”])
  • 属性查询(例如foo.bar)
  • 方法调用(例如foo.bar())
  • 列表索引查找(例如,foo [2])

系统使用有效的第一种查找类型。这是短路逻辑。

you can use the dot notation:

Dot lookups can be summarized like this: when the template system encounters a dot in a variable name, it tries the following lookups, in this order:

  • Dictionary lookup (e.g., foo[“bar”])
  • Attribute lookup (e.g., foo.bar)
  • Method call (e.g., foo.bar())
  • List-index lookup (e.g., foo[2])

The system uses the first lookup type that works. It’s short-circuit logic.


回答 3

您需要在此处找到(或定义)“ get”模板标签。

标签定义:

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

它的用法如下:

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

You need to find (or define) a ‘get’ template tag, for example, here.

The tag definition:

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

And it’s used like:

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

回答 4

使用字典项目:

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

Use Dictionary Items:

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

回答 5

django_template_filter 过滤器名称get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

django_template_filter filter name get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

回答 6

类似于@russian_spy的回答:

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

这可能适合分解更复杂的字典。

Similar to the answer by @russian_spy :

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

This might be suitable for breaking down more complex dictionaries.


回答 7

理想情况下,您将在以投票方式发现自己的选择对象上创建方法,或者在模型之间创建关系。执行字典查找的模板标记也将起作用。

Ideally, you would create a method on the choice object that found itself in votes, or create a relationship between the models. A template tag that performed the dictionary lookup would work, too.