У меня есть кое-что в settings.py, к которому я хотел бы получить доступ из шаблона, но я не могу понять, как это сделать. Я уже пробовал
{{CONSTANT_NAME}}
но это, похоже, не работает. Это возможно?
У меня есть кое-что в settings.py, к которому я хотел бы получить доступ из шаблона, но я не могу понять, как это сделать. Я уже пробовал
{{CONSTANT_NAME}}
но это, похоже, не работает. Это возможно?
Django предоставляет доступ к определенным, часто используемым константам настроек для шаблона, таким как settings.MEDIA_URL
, и некоторым языковым настройкам, если вы используете django, встроенные в общие представления, или передаете аргумент ключевого слова экземпляра контекста в функции ярлыка render_to_response
. Вот пример каждого случая:
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))
Оба эти представления будут иметь несколько часто используемых настроек, например settings.MEDIA_URL
, доступный для шаблона как {{ MEDIA_URL }}
и т. Д.
Если вы ищете доступ к другим константам в настройках, просто распакуйте нужные константы и добавьте их в контекстный словарь, который вы используете в своей функции просмотра, например:
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)
Теперь вы можете получить доступ к settings.FAVORITE_COLOR
в вашем шаблоне как {{ favorite_color }}
.
django-settings-export
, чтобы избежать необходимости писать этот код в каждом представлении.
- person qris; 14.11.2014
Если это значение, которое вы хотели бы иметь для каждого запроса и шаблона, используйте context-processors более уместен.
Вот как:
Создайте файл context_processors.py
в каталоге вашего приложения. Скажем, я хочу иметь значение ADMIN_PREFIX_VALUE
в каждом контексте:
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}
добавьте обработчик контекста в файл settings.py:
TEMPLATES = [{
# whatever comes before
'OPTIONS': {
'context_processors': [
# whatever comes before
"your_app.context_processors.admin_media",
],
}
}]
Используйте RequestContext
в своем представлении, чтобы добавить обработчики контекста в шаблон. render
ярлык делает это автоматически:
from django.shortcuts import render
def my_view(request):
return render(request, "index.html")
и, наконец, в вашем шаблоне:
...
<a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
...
context_process.py
рядом с моим settings.py
файлом и добавил "context_processors.admin_media"
в свой TEMPLATE_CONTEXT_PROCESSORS
список. Кроме того, вы можете добавить в свой ответ примечание о том, что значение по умолчанию для TEMPLATE_CONTEXT_PROCESSORS не пустое, поэтому, если какой-либо существующий код использует любое из значений, установленных этими процессорами контекста по умолчанию, они не будут работать, если вы не добавите их обратно. в список явно.
- person MiniQuark; 05.03.2013
render
, чтобы избежать явного включения RequestContext: https://docs.djangoproject.com/en/1.6/topics/http/shortcuts/#render
- person yndolok; 21.08.2014
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ..., 'APP_DIRS': False, 'OPTIONS': { 'context_processors': ( "django.contrib.auth.context_processors.auth", ... "my_app.context_processors.admin_media", ) 'loaders':..., }, }, ]
- person oriadam; 31.12.2015
context_processors.py
вы также можете сделать return {'ADMIN_MEDIA_URL': settings.ADMIN_MEDIA_PREFIX, 'ANOTHER_KEY':'another value'}
и {{ANOTHER_KEY}
также доступен
- person citynorman; 19.12.2017
Я считаю, что самый простой подход - использовать один настраиваемый тег шаблона:
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, "")
Использование:
{% settings_value "LANGUAGE_CODE" %}
{% settings_value "DATABASES" %}
? Этот вариант использования должен сделать очевидным, почему настройки недоступны в шаблонах с самого начала.
- person mkoistinen; 18.05.2013
templatetags
внутри вашего приложения с пустым __init__.py
файлом и этим кодом как settings.py
внутри этой папки. 2) в свой шаблон вы добавляете {% load settings %}
, а затем используете свой новый тег!
- person damio; 25.10.2016
if
на этом значении? как ты мог это использовать?
- person EsseTi; 19.04.2018
Ознакомьтесь с django-settings-export
(отказ от ответственности: я являюсь автором этого проекта).
Например...
$ pip install django-settings-export
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
'django_settings_export.settings_export',
],
},
},
]
MY_CHEESE = 'Camembert';
SETTINGS_EXPORT = [
'MY_CHEESE',
]
<script>var MY_CHEESE = '{{ settings.MY_CHEESE }}';</script>
render
а не render_to_response
- person Everett Toews; 17.07.2017
Другой способ сделать это - создать собственный тег шаблона, который позволит вам выудить значения из настроек.
@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))
Затем вы можете использовать:
{% value_from_settings "FQDN" %}
чтобы распечатать его на любой странице, не перепрыгивая через обручи контекстного процессора.
template.Variable()
. Использование str()
в экземпляре Variable
просто возвращает значение, которое было дано конструктору, дословно.
- person Michael Wehner; 27.04.2012
templatetags
с пустым __init__.py
в ней. Затем создайте там custom_tags.py
с помощью приведенного выше кода (не забудьте register = template.Library()
. Во-вторых, зарегистрируйтесь в INSTALLED_APPS = [..., 'your_app.templatetags', ..]
. В-третьих, в заголовке html-шаблона вам нужно загрузить модуль: {% load custom_tags %}
. И ТОГДА он будет работать: {% value_from_settings "A_PARAMETER_FROM_SETTINGS" %}
- person Constantine Kurbatov; 11.06.2021
Мне нравится решение Берислава, потому что на простых сайтах оно чистое и эффективное. Что мне НЕ нравится, так это демонстрация всех констант настроек волей-неволей. В итоге я сделал следующее:
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 ''
Использование:
{% settings_value "CONSTANT_NAME_1" %}
Это защищает любые константы, которые вы не назвали, от использования в шаблоне, и если вы хотите получить действительно необычный вид, вы можете установить кортеж в настройках и создать более одного тега шаблона для разных страниц, приложений или областей, и просто объедините локальный кортеж с кортежем настроек по мере необходимости, затем проанализируйте список, чтобы увидеть, приемлемо ли значение.
Я согласен, на сложном сайте это немного упрощенно, но есть значения, которые было бы неплохо есть универсально в шаблонах, и, похоже, это хорошо работает. Спасибо Бериславу за оригинальную идею!
if name in ALLOWABLE_VALUES: ...
- person frnhr; 22.03.2014
'val' in ('val_first', 'second_val',)
- это False
, здесь нет проблем с подстрокой.
- person frnhr; 05.04.2014
if
заявлении? я хочу проверить значение DEBUG
- person A.J.; 20.05.2015
Добавление ответа с полными инструкциями по созданию настраиваемого тега шаблона, который решает эту проблему, с помощью Django 2.0+
В папке приложения создайте папку под названием templatetags. В нем создайте __init__.py и custom_tags.py:
В custom_tags.py создайте функцию настраиваемого тега, которая обеспечивает доступ к произвольному ключу в константе settings:
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def get_setting(name):
return getattr(settings, name, "")
Чтобы понять этот код, я рекомендую прочитать раздел о простых тегах в документации Django.
Затем вам нужно сообщить Django об этом (и любом дополнительном) настраиваемом теге, загрузив этот файл в любой шаблон, в котором вы его будете использовать. Так же, как вам нужно загрузить встроенный статический тег:
{% load custom_tags %}
Когда он загружен, его можно использовать так же, как и любой другой тег, просто укажите конкретную настройку, которую вам нужно вернуть. Итак, если у вас есть переменная BUILD_VERSION в ваших настройках:
{% get_setting "BUILD_VERSION" %}
Это решение не будет работать с массивами, но если вам это нужно, вы можете добавить много логики в свои шаблоны.
Примечание. Более чистым и надежным решением, вероятно, было бы создание пользовательского обработчика контекста, в который вы добавляете необходимые настройки в контекст, доступный для всех шаблонов. Таким образом вы уменьшите риск ошибочного вывода конфиденциальных настроек в ваши шаблоны.
Добавьте этот код в файл с именем context_processors.py
:
from django.conf import settings as django_settings
def settings(request):
return {
'settings': django_settings,
}
Затем в файле настроек укажите путь, например 'speedy.core.base.context_processors.settings'
(с именем и путем вашего приложения) в 'context_processors'
настройках в TEMPLATES
.
(Вы можете увидеть, например, settings / base .py и context_processors. ру).
Затем вы можете использовать конкретную настройку в любом коде шаблона. Например:
{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}
Обновление. Приведенный выше код предоставляет шаблонам все настройки, включая конфиденциальную информацию, такую как ваш SECRET_KEY
. Хакер может злоупотребить этой функцией, чтобы отобразить такую информацию в шаблонах. Если вы хотите предоставить шаблонам только определенные настройки, используйте вместо этого этот код:
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,
}
SECRET_KEY
. Хакер может злоупотребить этой функцией, чтобы отобразить такую информацию в шаблонах.
- person Uri; 28.05.2020
TEMPLATES.OPTIONS.context_processors
в settings.py: 'myapp.context_processors.settings'
или более в общем '[APP_NAME].context_processors.settings'
где [APP_NAME] следует заменить на имя вашего приложения.
- person Sal Borrelli; 09.09.2020
Я улучшил ответ chrisdew (чтобы создать свой собственный тег) немного.
Сначала создайте файл yourapp/templatetags/value_from_settings.py
, в котором вы определяете свой собственный новый тег 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
Вы можете использовать этот тег в своем шаблоне через:
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}
или через
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}
Преимущество обозначения as ...
состоит в том, что это упрощает использование blocktrans
блоков с помощью простого {{my_fqdn}}
.
При использовании представления на основе классов:
#
# 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 }}
Приведенный выше пример из bchhun хорош, за исключением того, что вам нужно явно создать свой контекстный словарь из settings.py. Ниже НЕПРОВЕРЕННЫЙ пример того, как вы можете автоматически создать контекстный словарь из всех атрибутов в верхнем регистре settings.py (re: «^ [A-Z0-9 _] + $»).
В конце 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',
...
)
Если кто-то найдет этот вопрос так же, как я, я опубликую свое решение, которое работает на Django 2.0:
Этот тег присваивает переменной шаблона некоторое значение переменной settings.py:
Использование: {% 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 %}
См. Документацию Django о том, как создавать собственные теги шаблонов здесь: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
{% if settings_debug == True %}
на предложенный вами {% if settings_debug %}
- person NullIsNot0; 29.04.2019
Я обнаружил, что это самый простой подход для Django 1.3:
views.py
from local_settings import BASE_URL
def root(request):
return render_to_response('hero.html', {'BASE_URL': BASE_URL})
hero.html
var BASE_URL = '{{ JS_BASE_URL }}';
И IanSR, и bchhun предложили переопределить TEMPLATE_CONTEXT_PROCESSORS в настройках. Имейте в виду, что этот параметр имеет значение по умолчанию, которое может вызвать некоторые неприятные вещи, если вы переопределите его без повторной установки значений по умолчанию. Значения по умолчанию также изменились в последних версиях Django.
https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors
По умолчанию 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")
Если бы мы сравнили контекстные и шаблонные теги для одной переменной, то знание более эффективного варианта могло бы оказаться полезным. Однако, возможно, вам лучше погрузиться в настройки только из шаблонов, которым нужна эта переменная. В этом случае нет смысла передавать переменную во все шаблоны. Но если вы отправляете переменную в общий шаблон, такой как шаблон base.html, тогда это не имеет значения, поскольку шаблон base.html отображается при каждом запросе, поэтому вы можете использовать любой из методов.
Если вы решите использовать опцию шаблонных тегов, используйте следующий код, поскольку он позволяет вам передать значение по умолчанию на тот случай, если рассматриваемая переменная не определена.
Пример: get_from_settings my_variable как my_context_value
Пример: get_from_settings my_variable my_default как 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)
SITE_EXTRA_CONTEXT_DICT
в finalware, чтобы сделать это за вас.
- person un33k; 26.03.2016