I have some stuff in settings.py that I'd like to be able to access from a template, but I can't figure out how to do it. I already tried
{{CONSTANT_NAME}}
but that doesn't seem to work. Is this possible?
I have some stuff in settings.py that I'd like to be able to access from a template, but I can't figure out how to do it. I already tried
{{CONSTANT_NAME}}
but that doesn't seem to work. Is this possible?
If it's a value you'd like to have for every request & template, using a context processor is more appropriate.
Here's how:
Make a context_processors.py file in your app directory. Let's say I want to have the ADMIN_PREFIX_VALUE value in every context:
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}
add your context processor to your settings.py file:
TEMPLATES = [{
# whatever comes before
'OPTIONS': {
'context_processors': [
# whatever comes before
"your_app.context_processors.admin_media",
],
}
}]
Use RequestContext in your view to add your context processors in your template. The render shortcut does this automatically:
from django.shortcuts import render
def my_view(request):
return render(request, "index.html")
and finally, in your template:
...
<a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
...
Django provides access to certain, frequently-used settings constants to the template such as settings.MEDIA_URL and some of the language settings if you use django's built in generic views or pass in a context instance keyword argument in the render_to_response shortcut function. Here's an example of each case:
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))
These views will both have several frequently used settings like settings.MEDIA_URL available to the template as {{ MEDIA_URL }}, etc.
If you're looking for access to other constants in the settings, then simply unpack the constants you want and add them to the context dictionary you're using in your view function, like so:
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)
Now you can access settings.FAVORITE_COLOR on your template as {{ favorite_color }}.
Adding an answer with complete instructions for creating a custom template tag that solves this, with Django 2.0+
In your app-folder, create a folder called templatetags. In it, create __init__.py and custom_tags.py:
In the custom_tags.py create a custom tag function that provides access to an arbitrary key in the settings constant:
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def get_setting(name):
return getattr(settings, name, "")
To understand this code I recommend reading the section on simple tags in the Django docs.
Then, you need to make Django aware of this (and any additional) custom tag by loading this file in any template where you will use it. Just like you need to load the built in static tag:
{% load custom_tags %}
With it loaded it can be used just like any other tag, just supply the specific setting you need returned. So if you have a BUILD_VERSION variable in your settings:
{% get_setting "BUILD_VERSION" %}
This solution will not work with arrays, but if you need that you might be putting to much logic in your templates.
Note: A more clean and failsafe solution would probably be to make a custom context processor where you add the settings you need to a context available to all templates. This way you reduce the risk of outputting sensitive settings in your templates by mistake.
Add this code to a file called context_processors.py:
from django.conf import settings as django_settings
def settings(request):
return {
'settings': django_settings,
}
And then, in your settings file, include a path such as 'speedy.core.base.context_processors.settings' (with your app name and path) in the 'context_processors' settings in TEMPLATES.
(You can see for example settings/base.py and context_processors.py).
Then you can use the specific setting in any template code. For example:
{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}
Update: The code above exposes all the settings to templates, including sensitive information such as your SECRET_KEY. A hacker might abuse this feature to display such information in the templates. If you want to expose only specific settings to the templates, use this code instead:
def settings(request):
settings_in_templates = {}
for attr in ["SITE_ID", ...]: # Write here the settings you want to expose to the templates.
if (hasattr(django_settings, attr)):
settings_in_templates[attr] = getattr(django_settings, attr)
return {
'settings': settings_in_templates,
}
If someone finds this question like I did, then I'll post my solution which works on Django 2.0:
This tag assigns some settings.py variable value to template's variable:
Usage: {% get_settings_value template_var "SETTINGS_VAR" %}
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)
{% 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 %}
... do something ...
{% else %}
... do other stuff ...
{% endif %}
See Django's documentation how to create custom template tags here: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
For those who want to use @Berislav's approach (custom template tag) with if tag:
/app/templatetags/my_settings.py:
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def settings_value(name):
return getattr(settings, name, "")
Template file:
<!-- Load your tags -->
{% load my_settings %}
{% settings_value 'ENABLE_FEATURE_A' as ENABLE_FEATURE_A %}
{% if ENABLE_FEATURE_A %}
<!-- Feature A stuffs -->
{% endif %}
A more complete implementation.
APP_NAME = 'APP'
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def settings_value(name):
return getattr(settings, name, "")
<!DOCTYPE html>
{% load static %}
{% load settings_value %}
<head>
<title>{% settings_value "APP_NAME" %}</title>
...