Plantilla de Django cómo buscar un valor de diccionario con una variable

Resuelto Stan asked hace 12 años • 11 respuestas
mydict = {"key1":"value1", "key2":"value2"}

La forma habitual de buscar un valor de diccionario en una plantilla de Django es {{ mydict.key1 }}. {{ mydict.key2 }}¿Qué pasa si la clave es una variable de bucle? es decir:

{% for item in list %} # where item has an attribute NAME
  {{ mydict.item.NAME }} # I want to look up mydict[item.NAME]
{% endfor %}

mydict.item.NAMEfalla. ¿Cómo arreglar esto?

Stan avatar Nov 04 '11 01:11 Stan
Aceptado

Escribe un filtro de plantilla personalizado :

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

(Lo uso .getpara que si la clave está ausente, no devuelva ninguna. Si lo hace, dictionary[key]generará un KeyErrorentonces).

uso:

{{ mydict|get_item:item.NAME }}
culebrón avatar Nov 03 '2011 18:11 culebrón

Obtenga tanto la clave como el valor del diccionario en el bucle:

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

Esto me resulta más fácil de leer y evita la necesidad de codificación especial. De todos modos, normalmente necesito la clave y el valor dentro del bucle.

Paul Whipp avatar Jul 12 '2015 01:07 Paul Whipp

No puedes por defecto. El punto es el separador/activador para la búsqueda de atributos/búsqueda de claves/sección.

Los puntos tienen un significado especial en la representación de plantillas. Un punto en el nombre de una variable significa una búsqueda. Específicamente, cuando el sistema de plantillas encuentra un punto en el nombre de una variable, intenta las siguientes búsquedas, en este orden:

  • Búsqueda de diccionario. Ejemplo: foo["barra"]
  • Búsqueda de atributos. Ejemplo: foo.bar
  • Búsqueda de índice de lista. Ejemplo: foo[barra]

Pero puedes crear un filtro que te permita pasar un argumento:

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 }}
Yuji 'Tomita' Tomita avatar Nov 03 '2011 18:11 Yuji 'Tomita' Tomita

Para mí, crear un archivo Python nombrado template_filters.pyen mi aplicación con el contenido a continuación funcionó

# coding=utf-8
from django.template.base import Library

register = Library()


@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

el uso es como lo que dijo culebrón:

{{ mydict|get_item:item.NAME }}
AmiNadimi avatar Jun 29 '2017 19:06 AmiNadimi

Entorno: Django 2.2

  1. Código de ejemplo:


    from django.template.defaulttags import register

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

Puse este código en un archivo llamado template_filters.py en la carpeta de mi proyecto llamada portfoliomgr

  1. No importa dónde coloque su código de filtro, asegúrese de tener __init__.py en esa carpeta

  2. Agregue ese archivo a la sección de bibliotecas en la sección de plantillas en su archivo carpeta de proyecto/settings.py. Para mí, es 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. En tu código html carga la biblioteca

    
    {% load template_filters %}
    
Krishna avatar Jun 07 '2020 15:06 Krishna

Tuve una situación similar. Sin embargo, utilicé una solución diferente.

En mi modelo creo una propiedad que realiza la búsqueda en el diccionario. En la plantilla luego uso la propiedad.

En mi modelo: -

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

En mi plantilla: -

The state is: {{ item.state_ }}
sexybear2 avatar Oct 07 '2016 00:10 sexybear2