¿Puedo acceder a constantes en settings.py desde plantillas en Django?

Tengo algunas cosas en settings.py a las que me gustaría tener acceso desde una plantilla, pero no puedo encontrar la manera de hacerlo. Ya lo intenté

{{CONSTANT_NAME}} 

pero eso no parece funcionar. es posible?

Django proporciona acceso a ciertas constantes de configuración de uso frecuente a la plantilla como settings.MEDIA_URL y algunas configuraciones de idioma si usa las vistas genéricas integradas de django o pasa un argumento de palabra clave de instancia de contexto en la función de acceso directo render_to_response . Aquí hay un ejemplo de cada caso:

 from django.shortcuts import render_to_response from django.template import RequestContext from django.views.generic.simple import direct_to_template def my_generic_view(request, template='my_template.html'): return direct_to_template(request, template) def more_custom_view(request, template='my_template.html'): return render_to_response(template, {}, context_instance=RequestContext(request)) 

Estas vistas tendrán varias configuraciones usadas con frecuencia, como settings.MEDIA_URL . {{ MEDIA_URL }} disponible para la plantilla como {{ MEDIA_URL }} , etc.

Si está buscando acceso a otras constantes en la configuración, simplemente descomprima las constantes que desee y agréguelas al diccionario de contexto que esté utilizando en la función de visualización, de esta forma:

 from django.conf import settings from django.shortcuts import render_to_response def my_view_function(request, template='my_template.html'): context = {'favorite_color': settings.FAVORITE_COLOR} return render_to_response(template, context) 

Ahora puede acceder a settings.FAVORITE_COLOR en su plantilla como {{ favorite_color }} .

Si es un valor que le gustaría tener para cada solicitud y plantilla, usar un procesador de contexto es más apropiado.

Así es cómo:

  1. Cree un archivo context_processors.py en el directorio de su aplicación. Digamos que quiero tener el valor ADMIN_PREFIX_VALUE en cada contexto:

     from django.conf import settings # import the settings file def admin_media(request): # return the value you want as a dictionnary. you may add multiple values in there. return {'ADMIN_MEDIA_URL': settings.ADMIN_MEDIA_PREFIX} 
  2. agregue su procesador de contexto a su archivo settings.py :

     TEMPLATES = [{ # whatever comes before 'OPTIONS': { 'context_processors': [ # whatever comes before "your_app.context_processors.admin_media", ], } }] 
  3. Use RequestContext en su vista para agregar los procesadores de contexto en su plantilla. El atajo de render hace esto automáticamente:

     from django.shortcuts import render def my_view(request): return render(request, "index.html") 
  4. y finalmente, en tu plantilla:

     ... path to admin media ... 

Encuentro que el enfoque más simple es una sola etiqueta de plantilla:

 from django import template from django.conf import settings register = template.Library() # settings value @register.simple_tag def settings_value(name): return getattr(settings, name, "") 

Uso:

 {% settings_value "LANGUAGE_CODE" %} 

Echa un vistazo a django-settings-export (descargo de responsabilidad: soy el autor de este proyecto).

Por ejemplo…

 $ pip install django-settings-export 

settings.py

 TEMPLATES = [ { 'OPTIONS': { 'context_processors': [ 'django_settings_export.settings_export', ], }, }, ] MY_CHEESE = 'Camembert'; SETTINGS_EXPORT = [ 'MY_CHEESE', ] 

template.html

  

Otra forma de hacerlo es crear una etiqueta de plantilla personalizada que le permita extraer valores de la configuración.

 @register.tag def value_from_settings(parser, token): try: # split_contents() knows not to split quoted strings. tag_name, var = token.split_contents() except ValueError: raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0] return ValueFromSettings(var) class ValueFromSettings(template.Node): def __init__(self, var): self.arg = template.Variable(var) def render(self, context): return settings.__getattr__(str(self.arg)) 

Puede usar:

 {% value_from_settings "FQDN" %} 

para imprimirlo en cualquier página, sin saltar a través de los aros del procesador de contexto.

Me gusta la solución de Berislav, porque en sitios simples, es limpia y efectiva. Lo que NO me gusta es exponer todas las constantes de configuración de cualquier manera. Entonces, lo que terminé haciendo fue esto:

 from django import template from django.conf import settings register = template.Library() ALLOWABLE_VALUES = ("CONSTANT_NAME_1", "CONSTANT_NAME_2",) # settings value @register.simple_tag def settings_value(name): if name in ALLOWABLE_VALUES: return getattr(settings, name, '') return '' 

Uso:

 {% settings_value "CONSTANT_NAME_1" %} 

Esto protege las constantes que no haya nombrado de su uso en la plantilla, y si desea ser realmente elegante, puede establecer una tupla en la configuración y crear más de una etiqueta de plantilla para diferentes páginas, aplicaciones o áreas, y simplemente combine una tupla local con la configuración tuple según sea necesario, luego haga la lista de comprensión para ver si el valor es aceptable.
Estoy de acuerdo, en un sitio complejo, esto es un poco simplista, pero hay valores que sería bueno tener universalmente en las plantillas, y esto parece funcionar muy bien. ¡Gracias a Berislav por la idea original!

Mejoré un poco la respuesta de Chrisdew (para crear tu propia etiqueta).

Primero, crea el archivo yourapp/templatetags/value_from_settings.py en el que defines tu nueva etiqueta value_from_settings :

 from django.template import TemplateSyntaxError, Variable, Node, Variable, Library from yourapp import settings register = Library() # I found some tricks in URLNode and url from defaulttags.py: # https://code.djangoproject.com/browser/django/trunk/django/template/defaulttags.py @register.tag def value_from_settings(parser, token): bits = token.split_contents() if len(bits) < 2: raise TemplateSyntaxError("'%s' takes at least one " \ "argument (settings constant to retrieve)" % bits[0]) settingsvar = bits[1] settingsvar = settingsvar[1:-1] if settingsvar[0] == '"' else settingsvar asvar = None bits = bits[2:] if len(bits) >= 2 and bits[-2] == 'as': asvar = bits[-1] bits = bits[:-2] if len(bits): raise TemplateSyntaxError("'value_from_settings' didn't recognise " \ "the arguments '%s'" % ", ".join(bits)) return ValueFromSettings(settingsvar, asvar) class ValueFromSettings(Node): def __init__(self, settingsvar, asvar): self.arg = Variable(settingsvar) self.asvar = asvar def render(self, context): ret_val = getattr(settings,str(self.arg)) if self.asvar: context[self.asvar] = ret_val return '' else: return ret_val 

Puedes usar esta etiqueta en tu Plantilla a través de:

 {% load value_from_settings %} [...] {% value_from_settings "FQDN" %} 

o vía

 {% load value_from_settings %} [...] {% value_from_settings "FQDN" as my_fqdn %} 

La ventaja de la notación as ... es que esto hace que sea fácil de usar en bloques de bloques mediante un {{my_fqdn}} simple.

El ejemplo anterior de bchhun es bueno, excepto que necesitas construir explícitamente tu diccionario de contexto desde settings.py. A continuación se muestra un ejemplo NO DETALLADO de cómo se puede construir automáticamente el diccionario de contexto a partir de todos los atributos en mayúsculas de settings.py (re: “^ [A-Z0-9 _] + $”).

Al final de settings.py:

 _context = {} local_context = locals() for (k,v) in local_context.items(): if re.search('^[A-Z0-9_]+$',k): _context[k] = str(v) def settings_context(context): return _context TEMPLATE_CONTEXT_PROCESSORS = ( ... 'myproject.settings.settings_context', ... ) 

Si usa una vista basada en clase:

 # # in settings.py # YOUR_CUSTOM_SETTING = 'some value' # # in views.py # from django.conf import settings #for getting settings vars class YourView(DetailView): #assuming DetailView; whatever though # ... def get_context_data(self, **kwargs): context = super(YourView, self).get_context_data(**kwargs) context['YOUR_CUSTOM_SETTING'] = settings.YOUR_CUSTOM_SETTING return context # # in your_template.html, reference the setting like any other context variable # {{ YOUR_CUSTOM_SETTING }} 

Si alguien encuentra esta pregunta como yo lo hice, entonces publicaré mi solución que funciona en Django 2.0:

Esta etiqueta asigna algún valor de variable settings.py a la variable de la plantilla:

Uso: {% get_settings_value template_var "SETTINGS_VAR" %}

app / templatetags / my_custom_tags.py:

 from django import template from django.conf import settings register = template.Library() class AssignNode(template.Node): def __init__(self, name, value): self.name = name self.value = value def render(self, context): context[self.name] = getattr(settings, self.value.resolve(context, True), "") return '' @register.tag('get_settings_value') def do_assign(parser, token): bits = token.split_contents() if len(bits) != 3: raise template.TemplateSyntaxError("'%s' tag takes two arguments" % bits[0]) value = parser.compile_filter(bits[2]) return AssignNode(bits[1], value) 

Su plantilla:

 {% load my_custom_tags %} # Set local template variable: {% get_settings_value settings_debug "DEBUG" %} # Output settings_debug variable: {{ settings_debug }} # Use variable in if statement: {% if settings_debug == True %} ... do something ... {% else %} ... do other stuff ... {% endif %} 

Consulte la documentación de Django sobre cómo crear tags de plantilla personalizadas aquí: https://docs.djangoproject.com/es/2.0/howto/custom-template-tags/

Agregando una respuesta con instrucciones completas para crear una etiqueta de plantilla personalizada que resuelva esto, con Django 2.0

En su carpeta de aplicaciones, cree una carpeta llamada templatetags . En él, crea __init__.py y custom_tags.py :

Estructura de carpetas de etiquetas personalizadas

En custom_tags.py crea una función de etiqueta personalizada que proporciona acceso a una clave arbitraria en la constante de configuración :

 from django import template from django.conf import settings register = template.Library() @register.simple_tag def get_setting(name): return getattr(settings, name, "") 

Para entender este código, recomiendo leer la sección de tags simples en los documentos de Django.

Luego, debe informar a Django sobre esta (y cualquier otra) etiqueta personalizada cargando este archivo en cualquier plantilla donde lo use. Al igual que necesita cargar la etiqueta estática incorporada:

 {% load custom_tags %} 

Una vez cargado, se puede usar como cualquier otra etiqueta, solo debe proporcionar la configuración específica que necesita. Entonces, si tiene una variable BUILD_VERSION en su configuración:

 {% get_setting "BUILD_VERSION" %} 

Esta solución no funcionará con arreglos, pero si la necesita, puede estar poniendo mucha lógica en sus plantillas.

Tanto IanSR como bchhun sugirieron reemplazar TEMPLATE_CONTEXT_PROCESSORS en la configuración. Tenga en cuenta que esta configuración tiene un valor predeterminado que puede causar algunos problemas si lo reemplaza sin volver a establecer los valores predeterminados. Los valores predeterminados también han cambiado en las versiones recientes de Django.

https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors

El valor predeterminado TEMPLATE_CONTEXT_PROCESSORS:

 TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.contrib.messages.context_processors.messages") 

Encontré este es el enfoque más simple para Django 1.3:

  1. views.py

     from local_settings import BASE_URL def root(request): return render_to_response('hero.html', {'BASE_URL': BASE_URL}) 
  2. hero.html

     var BASE_URL = '{{ JS_BASE_URL }}'; 

Si tuviéramos que comparar tags de contexto vs. plantilla en una sola variable, conocer la opción más eficiente podría ser benéfica. Sin embargo, es mejor que te sumerjas en la configuración solo desde plantillas que necesitan esa variable. En ese caso, no tiene sentido pasar la variable a todas las plantillas. Pero si está enviando la variable a una plantilla común, como la plantilla base.html, entonces no importaría ya que la plantilla base.html se representa en cada solicitud, por lo que puede usar cualquiera de los métodos.

Si decide ir con la opción de tags de plantilla, utilice el siguiente código ya que le permite pasar un valor predeterminado , en caso de que la variable en cuestión no estuviera definida.

Ejemplo: get_from_settings my_variable como my_context_value

Ejemplo: get_from_settings my_variable my_default as my_context_value

 class SettingsAttrNode(Node): def __init__(self, variable, default, as_value): self.variable = getattr(settings, variable, default) self.cxtname = as_value def render(self, context): context[self.cxtname] = self.variable return '' def get_from_setting(parser, token): as_value = variable = default = '' bits = token.contents.split() if len(bits) == 4 and bits[2] == 'as': variable = bits[1] as_value = bits[3] elif len(bits) == 5 and bits[3] == 'as': variable = bits[1] default = bits[2] as_value = bits[4] else: raise TemplateSyntaxError, "usage: get_from_settings variable default as value " \ "OR: get_from_settings variable as value" return SettingsAttrNode(variable=variable, default=default, as_value=as_value) get_from_setting = register.tag(get_from_setting)