ChatGPT解决这个技术问题 Extra ChatGPT

在 Django 模板中使用变量作为字典键

I'd like to use a variable as an key in a dictionary in a Django template. I can't for the life of me figure out how to do it. If I have a product with a name or ID field, and ratings dictionary with indices of the product IDs, I'd like to be able to say:

{% for product in product_list %}
     <h1>{{ ratings.product.id }}</h1>
{% endfor %}

In python this would be accomplished with a simple

ratings[product.id]

But I can't make it work in the templates. I've tried using with... no dice. Ideas?


T
Thorin Schiffer

Create a template tag like this (in yourproject/templatetags):

@register.filter
def keyvalue(dict, key):    
    return dict[key]

Usage:

{{dictionary|keyvalue:key_variable}}

You also need a bunch of peripheral stuff to make this work so make sure you check out the documentation: docs.djangoproject.com/en/dev/howto/custom-template-tags
Can this be chained for nested dicts? Something like {{dictionary|keyvalue:key_variable|keyvalue:another_key}} ?
Theoretically yes, try it out ;)
This is such a trivial thing. Why doesn't django support this out of the box?
@mango because they want to stay away from logic in templates and encourage putting it in the view
c
cji

You need to prepare your data beforehand, in this case you should pass list of two-tuples to your template:

{% for product, rating in product_list %}
    <h1>{{ product.name }}</h1><p>{{ rating }}</p>
{% endfor %}

Thanks cji! I was trying to avoid another object, but it doesn't really matter... it's all cached anyway.
You don't need to prep the data in the view, you can achieve the same thing by calling items on the dictionary that's already in the context -- {% for product, rating in product_list.items %} will work.
P
Patrick

Building on eviltnan's answer, his filter will raise an exception if key isn't a key of dict.

Filters should never raise exceptions, but should fail gracefully. This is a more robust/complete answer:

@register.filter
def keyvalue(dict, key):    
    try:
        return dict[key]
    except KeyError:
        return ''

Basically, this would do the same as dict.get(key, '') in Python code, and could also be written that way if you don't want to include the try/except block, although it is more explicit.


instead of dict[key] you just use the built-in python dictionary get method. e.g.: return dict.get(key, '')
You should also catch a potential TypeError. Parameter "dict" is not guaranteed to be a Python dict.
p
podshumok

There is a very dirty solution:

<div>We need d[{{ k }}]</div>

<div>So here it is:
{% for key, value in d.items %}
    {% if k == key %}
        {{ value }}
    {% endif %}
{% endfor %}
</div>

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅