Могу ли я получить доступ к константам в settings.py из шаблонов в Django?

У меня есть кое-что в settings.py, к которому я хотел бы получить доступ из шаблона, но я не могу понять, как это сделать. Я уже пробовал

{{CONSTANT_NAME}}

но это, похоже, не работает. Это возможно?


person Paul Wicks    schedule 11.01.2009    source источник
comment
Если вы ищете, как передать настройку каждому ответу, посмотрите ответ bchunn о процессорах контекста.   -  person Zags    schedule 01.04.2015
comment
Ответ от @jkbrzt - это готовое решение, которое быстро и легко решает эту проблему. Будущие читатели должны взглянуть на этот stackoverflow.com/a/25841039/396005 поверх принятого ответа.   -  person Bron Davies    schedule 28.09.2016


Ответы (15)


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 }}.

person prairiedogg    schedule 11.01.2009
comment
Стоит отметить, что конкретные значения, добавляемые с помощью RequestContext, зависят от значения TEMPLATE_CONTEXT_PROCESSORS. Таким образом, если вы хотите, чтобы дополнительные значения передавались повсюду, просто напишите свой собственный обработчик контекста и добавьте его в TEMPLATE_CONTEXT_PROCESSORS. - person Carl Meyer; 26.01.2009
comment
Что касается согласованности, то в общих представлениях и во многих приложениях core и contrib дополнительный контекст называется extra_context, и очень часто он включается в аргументы представления. - person Soviut; 01.06.2009
comment
Django предоставляет доступ к некоторым, часто используемым константам настроек для шаблона, таким как settings.MEDIA_URL. Похоже, это не работает в Django 1.3, хотя я, вероятно, использую его неправильно. Есть ли документация по этой функции? - person SystemParadox; 28.10.2011
comment
есть ли какие-нибудь советы по передаче переменных настроек в каждом шаблоне? - person asofyan; 01.05.2013
comment
@asofyan да, добавить создать собственный обработчик контекста шаблона и добавить в TEMPLATE_CONTEXT_PROCESSORS в settings.py. - person Paolo; 08.10.2013
comment
Обязательно посмотрите django-settings-export, чтобы избежать необходимости писать этот код в каждом представлении. - person qris; 14.11.2014

Если это значение, которое вы хотели бы иметь для каждого запроса и шаблона, используйте context-processors более уместен.

Вот как:

  1. Создайте файл 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}
    
  2. добавьте обработчик контекста в файл settings.py:

    TEMPLATES = [{
        # whatever comes before
        'OPTIONS': {
            'context_processors': [
                # whatever comes before
                "your_app.context_processors.admin_media",
            ],
        }
    }]
    
  3. Используйте RequestContext в своем представлении, чтобы добавить обработчики контекста в шаблон. render ярлык делает это автоматически:

    from django.shortcuts import render
    
    def my_view(request):
        return render(request, "index.html")
    
  4. и, наконец, в вашем шаблоне:

    ...
    <a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
    ...
    
person bchhun    schedule 11.01.2009
comment
Обратной стороной этого подхода является то, что вам необходимо явно связать определенные параметры в settings.py, которые вы хотите сделать доступными для средства визуализации контекста. Я мог бы представить решение, которое будет использовать соглашение о прописных атрибутах в settings.py и автоматически строить контекст. Я добавлю пример ниже как отдельный ответ. - person IanSR; 28.03.2011
comment
@MarkEssel Эти обручи сделаны так, чтобы переменная была доступна в каждом представлении, которое вы создадите, если оно использует функцию RequestContext. Вы всегда можете получить переменную настроек вручную в каждом представлении. Я бы выбрал многоразовый контекстный процессор в любое время вместо старого доброго «Копировать и вставить». - person bchhun; 25.01.2012
comment
изо всех сил стараюсь избегать копирования / вставки везде, где это возможно. будет ли каждое приложение (в рамках проекта) требовать context_processor.py, есть ли способ создать один context_processor для всех из них? - person Mark Essel; 25.01.2012
comment
@MarkEssel Хороший вопрос. Без дальнейших исследований я бы сказал, что невозможно разделить процессоры контекста между приложениями. - person bchhun; 25.01.2012
comment
@bchhun Я только что тестировал (Django 1.3): совместное использование контекстного процессора между приложениями работает нормально. :-) Я положил context_process.py рядом с моим settings.py файлом и добавил "context_processors.admin_media" в свой TEMPLATE_CONTEXT_PROCESSORS список. Кроме того, вы можете добавить в свой ответ примечание о том, что значение по умолчанию для TEMPLATE_CONTEXT_PROCESSORS не пустое, поэтому, если какой-либо существующий код использует любое из значений, установленных этими процессорами контекста по умолчанию, они не будут работать, если вы не добавите их обратно. в список явно. - person MiniQuark; 05.03.2013
comment
@MarkEssel Совсем не больно - он просто все объяснил. На самом деле это всего 6 коротких строк (шаги 1 и 2). В любом случае для большинства шаблонов требуются шаги 3 и 4 или их эквиваленты. - person Rick Westera; 20.01.2014
comment
MiniQuark и @Rrrrrrrrrk ах, отлично. После этого комментария не работал с django. Спасибо за ответ! - person Mark Essel; 21.01.2014
comment
@bchhun, это все еще не так просто, как использовать конфигурационную переменную непосредственно в шаблоне; например для регистрации django я хотел бы иметь возможность добавить протокол (http или https) в качестве настраиваемого параметра в шаблоне электронного письма для активации, и самым простым способом было бы сделать его настройкой. Вместо этого мне пришлось бы решить, как использовать другой обработчик контекста со сторонним приложением. Или я неправильно понял? - person Rob Grant; 17.07.2014
comment
Первоначально немного запутано в настройке, но это действительно хорошее решение - person user; 17.08.2014
comment
Начиная с Django 1.3, вы можете использовать ярлык render, чтобы избежать явного включения RequestContext: https://docs.djangoproject.com/en/1.6/topics/http/shortcuts/#render - person yndolok; 21.08.2014
comment
Я нахожу здесь ссылку на создание собственных контекстных процессоров: docs.djangoproject.com/en/1.8/ref/templates/api/ (текущая ссылка из контекстного процессора в ответе дает страницу, не найденную) - person Marjorie Roswell; 07.04.2015
comment
Сработало у меня, без шага 3! Обратите внимание, что начиная с django 1.8 вам нужно поместить обработчик контекста в другое место, например: 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
comment
Отличный материал! Для записи в context_processors.py вы также можете сделать return {'ADMIN_MEDIA_URL': settings.ADMIN_MEDIA_PREFIX, 'ANOTHER_KEY':'another value'} и {{ANOTHER_KEY} также доступен - person citynorman; 19.12.2017
comment
Безусловно, лучший ответ на этот вопрос, если я искал ответ только потому, что искал еще более простой способ ... Я хотел бы добавить здесь одно слово предостережения. context_processors блокируются, поэтому выполнение чего-либо, кроме простого вычисления или возврата строки, может замедлить каждый запрос, особенно если вы не ограничиваете использование контекстного процессора определенными конечными точками. - person AppHandwerker; 04.09.2020

Я считаю, что самый простой подход - использовать один настраиваемый тег шаблона:

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" %}
person Berislav Lopac    schedule 10.10.2011
comment
Мне нравится иметь доступ по запросу к любым настройкам в шаблонах, и это элегантно обеспечивает это. Это действительно намного лучше, чем другие ответы, если вы часто будете использовать различные настройки в своих шаблонах: 1) Принятый ответ несовместим или неуклюжий с представлениями на основе классов. 2) При использовании решения для обработки контекста шаблонов, за которое проголосовало большинство, вам нужно будет указать отдельные настройки (или все), и оно будет запускаться для каждого отдельного запроса, который отображает шаблон - неэффективно! 3) Это проще, чем более сложный тег выше. - person B Robster; 19.08.2012
comment
@BenRoberts Я согласен, что это элегантное решение ... но только для крошечных проектов с одним разработчиком, который делает все. Если у вас есть отдельные люди / команды для проектирования и разработки, то это решение, вероятно, наихудшее. Что мешает дизайнеру злоупотреблять этим тегом, используя что-то вроде: {% settings_value "DATABASES" %}? Этот вариант использования должен сделать очевидным, почему настройки недоступны в шаблонах с самого начала. - person mkoistinen; 18.05.2013
comment
Что ж, вы всегда можете расширить мой пример, включив в него список настроек, которые вы позволяете вызывать таким образом; если вызывается не включенный в список, просто верните простую пустую строку. - person Berislav Lopac; 18.05.2013
comment
@mkoistinen Я думаю, вы сделали несколько хороших замечаний. Я работаю с небольшой командой, и проверка кода устраняет любые грубые ошибки, подобные упомянутой вами (а я ничего подобного не видел). В проекте с открытым исходным кодом или в большой команде я могу увидеть, чем будут отличаться расчеты. Если команда вырастет до такой степени, что риск становится реальным, я бы предпочел просто добавлять настройки непосредственно в контекст на разовой основе (второй фрагмент кода в принятом ответе) вместо использования контекстного процессора, который запускается для каждого отдельного запроса. ... - person B Robster; 29.05.2013
comment
Вы можете повторить код для каждого выставленного параметра def LANGUAGE_CODE (): return settings.LANGUAGE_CODE, чтобы предотвратить злоупотребления. - person laffuste; 15.08.2013
comment
Мы все здесь взрослые по согласию - person frnhr; 22.03.2014
comment
Простите меня за то, что я новичок. Куда вы положили этот код? Views.py? Или в новом файле? - person Noel Llevares; 07.06.2014
comment
@Berislav Lopac отличный пример, но я думаю, что изменение его, чтобы разрешить только настройки из белого списка, сделало бы его еще лучше. - person stupidbodo; 10.04.2015
comment
чтобы было понятно для других, вам необходимо: 1) создать папку templatetags внутри вашего приложения с пустым __init__.py файлом и этим кодом как settings.py внутри этой папки. 2) в свой шаблон вы добавляете {% load settings %}, а затем используете свой новый тег! - person damio; 25.10.2016
comment
что, если вам нужен if на этом значении? как ты мог это использовать? - person EsseTi; 19.04.2018
comment
Спасибо @BerislavLopac, это самый простой способ - person Alessio; 21.05.2019
comment
Для тех, кто задается вопросом, почему вышеуказанное не работает, появляется сообщение об ошибке: TemplateSyntaxError: 'settings_value' не является зарегистрированной библиотекой тегов - ›вам необходимо перезагрузить сервер. - person angelos_lex; 18.06.2019
comment
Модератор удалил все мои правки, чтобы сделать этот пост более понятным. Чтобы это работало, вам нужно следовать инструкциям @damio. - person Dan Walters; 27.11.2019
comment
Ответ предполагает, что вы достаточно знакомы с Django, чтобы знать, как устанавливать собственные теги шаблонов. Для наглядности я добавил ссылку на соответствующую страницу документации. - person Berislav Lopac; 28.11.2019
comment
Есть ли способ использовать эту переменную для логики. {% if settings_value DEV == True%} приводит к: Неиспользованный "DEV" в конце выражения if. - person Dan Walters; 09.12.2019
comment
Для этого вам нужно будет настроить переменную: docs.djangoproject.com/en/3.0/howto/custom-template-tags/ - person Berislav Lopac; 10.12.2019
comment
В дополнение к @damio Не забудьте перезапустить сервер разработки, чтобы загрузить новый тег templatetag. - person Jean Zombie; 28.05.2020

Ознакомьтесь с django-settings-export (отказ от ответственности: я являюсь автором этого проекта).

Например...

$ 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

<script>var MY_CHEESE = '{{ settings.MY_CHEESE }}';</script>
person Jakub Roztocil    schedule 15.09.2014
comment
И обратите внимание, что в ваших представлениях вам необходимо использовать render а не render_to_response - person Everett Toews; 17.07.2017
comment
У меня аналогичное требование к чтению значений из настроек в шаблонах, но я получаю ошибку 500, когда добавляю django_settings_export.settings_export в файл настроек. Можете ли вы предложить, что я здесь делаю не так - person Piyush Sahu; 18.01.2018
comment
Это 2019 год, и я использую его в своем проекте. Спасибо! - person sivabudh; 11.03.2019
comment
Я согласен с @sivabudh. Для меня это также лучшее решение, потому что 1. Оно централизовано, что означает, что мне не нужны дополнительные папки и файлы, 2. Я вижу пространство имен настроек в моем шаблоне, что очень полезно для получения ссылок на многие приложения. - person ywiyogo; 25.04.2019

Другой способ сделать это - создать собственный тег шаблона, который позволит вам выудить значения из настроек.

@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" %}

чтобы распечатать его на любой странице, не перепрыгивая через обручи контекстного процессора.

person fadedbee    schedule 08.03.2011
comment
Я думаю, что это наиболее элегантное решение, так как оно работает как dropin без изменения кода. - person flying sheep; 05.10.2011
comment
что вы можете оставить остальную часть вашего приложения без изменений: вы добавляете один тег и используете его, вместо того, чтобы добавлять процессоры контекста (что означает, что вам нужно редактировать свое приложение в нескольких местах) - person flying sheep; 11.12.2011
comment
@Mark - в produi / src / produi / template_utils / templatetags / custom_template_filters.py ссылка на шаблон_utils из settings.py INSTALLED_APPS - также см. docs.djangoproject.com/en/dev/howto/custom-template-tags - person fadedbee; 26.01.2012
comment
оцените помощь, Крис, добавил приложение mutil с подкаталогом templatetags, включая custom_template_filters. По-прежнему появляется ошибка в homepage.html Недействительный тег блока: 'value_from_settings', ожидаемый 'endblock' или 'endblock banner' - person Mark Essel; 27.01.2012
comment
Я думаю, что это противоречит явному лучше, чем неявному, используя версию декоратора контекста, вы выбираете, какие именно настройки выставлять. - person sjh; 28.02.2012
comment
Пока я использую это решение, за исключением того, что я не могу правильно использовать getattr для объекта настроек. - person rhigdon; 28.03.2012
comment
@chrisdew не проблема. Для моей конкретной проблемы была удобная запись в базе данных для имени приложения, доступная через администратора. Я закончил базовое приложение в январе-феврале и снова переключился на Rails. Это был забавный опыт, и я копаюсь в Python, хотя я не в восторге от django. - person Mark Essel; 04.04.2012
comment
Я не думаю, что в этом примере нужен template.Variable(). Использование str() в экземпляре Variable просто возвращает значение, которое было дано конструктору, дословно. - person Michael Wehner; 27.04.2012
comment
Я потратил некоторое время на то, чтобы все работало правильно, как предлагается в этом ответе ... Во-первых, вам нужно создать новую папку в папке вашего приложения с именем 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" %}

Это защищает любые константы, которые вы не назвали, от использования в шаблоне, и если вы хотите получить действительно необычный вид, вы можете установить кортеж в настройках и создать более одного тега шаблона для разных страниц, приложений или областей, и просто объедините локальный кортеж с кортежем настроек по мере необходимости, затем проанализируйте список, чтобы увидеть, приемлемо ли значение.
Я согласен, на сложном сайте это немного упрощенно, но есть значения, которые было бы неплохо есть универсально в шаблонах, и, похоже, это хорошо работает. Спасибо Бериславу за оригинальную идею!

person MontyThreeCard    schedule 06.02.2014
comment
почему бы просто не if name in ALLOWABLE_VALUES: ... - person frnhr; 22.03.2014
comment
Потому что я думал, что поступаю умно, и хотел, чтобы подстроки не запускали параметры var. ;-) Возврат, вероятно, должен быть таким: return getattr (settings, is_allowable, '') - person MontyThreeCard; 05.04.2014
comment
Просто чтобы прояснить для всех, кому интересно: 'val' in ('val_first', 'second_val',) - это False, здесь нет проблем с подстрокой. - person frnhr; 05.04.2014
comment
Как я могу использовать это в if заявлении? я хочу проверить значение DEBUG - person A.J.; 20.05.2015
comment
Если кому-то понадобится версия с включенным повторным подключением, gist.github.com/BrnoPCmaniak/632f56ddb90786108b3ddddb90786108b3 - person Filip Dobrovolný; 06.01.2017

Добавление ответа с полными инструкциями по созданию настраиваемого тега шаблона, который решает эту проблему, с помощью 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" %}

Это решение не будет работать с массивами, но если вам это нужно, вы можете добавить много логики в свои шаблоны.

Примечание. Более чистым и надежным решением, вероятно, было бы создание пользовательского обработчика контекста, в который вы добавляете необходимые настройки в контекст, доступный для всех шаблонов. Таким образом вы уменьшите риск ошибочного вывода конфиденциальных настроек в ваши шаблоны.

person Andreas Bergström    schedule 25.04.2018

Добавьте этот код в файл с именем 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,
    }
person Uri    schedule 28.12.2018
comment
Я столкнулся с этой проблемой вчера, нашел этот пост, затем 2 других и сообщение в блоге и почувствовал, что каждый из них был слишком сложным (к сожалению, я не продвинулся так далеко вниз по странице, позор мне). Итак, я закончил свой собственный, который ИМЕННО это решение. Я только что вернулся, потому что меня беспокоило, что люди рекомендуют плагины и целую кучу кода, когда эта функция ^^^ из трех строк и одна строка меняются в settings.py. - person DXM; 28.05.2020
comment
@DXM Спасибо! - person Uri; 28.05.2020
comment
Фактически мое решение предоставляет все настройки шаблонам, включая конфиденциальную информацию, такую ​​как SECRET_KEY. Хакер может злоупотребить этой функцией, чтобы отобразить такую ​​информацию в шаблонах. - person Uri; 28.05.2020
comment
ну ... отлично, теперь у моего веб-сайта такая же проблема :) Но ... я могу что-то упустить, но уверены ли мы, что есть проблема? Шаблоны по сути такие же, как исходный код вашего сайта, не так ли? Они хранятся на стороне сервера и недоступны непосредственно из внешнего интерфейса. Если хакер может изменить шаблон, тогда он сможет изменить любой файл .py. - person DXM; 29.05.2020
comment
@DXM Да, в целом я думаю, что вы правы. Шаблоны похожи на исходный код. И если у хакера есть доступ к вашему исходному коду, он в любом случае может получить любые данные из ваших настроек, изменив ваш исходный код. - person Uri; 29.05.2020
comment
Это, безусловно, самое простое и чистое решение, спасибо. Я только хочу добавить небольшое примечание, которое может сэкономить время будущим читателям: вам не нужно устанавливать speedy.net или какое-либо другое внешнее приложение, чтобы это решение работало. Просто поместите файл context_processors.py в каталог основного приложения (например, myapp /) и добавьте следующую строку в раздел 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}}.

person pklaus    schedule 14.06.2011

При использовании представления на основе классов:

#
# 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 }}
person Bill Paetzke    schedule 28.04.2013

Приведенный выше пример из 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',
...
)
person IanSR    schedule 28.03.2011

Если кто-то найдет этот вопрос так же, как я, я опубликую свое решение, которое работает на Django 2.0:

Этот тег присваивает переменной шаблона некоторое значение переменной settings.py:

Использование: {% get_settings_value template_var "SETTINGS_VAR" %}

приложение / 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)

Ваш шаблон:

{% 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/

person NullIsNot0    schedule 17.01.2018
comment
Спасибо @ user66081! Изменен {% if settings_debug == True %} на предложенный вами {% if settings_debug %} - person NullIsNot0; 29.04.2019

Я обнаружил, что это самый простой подход для 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 }}';
    
person Michael    schedule 23.08.2013

И 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")
person MrOodles    schedule 23.11.2011

Если бы мы сравнили контекстные и шаблонные теги для одной переменной, то знание более эффективного варианта могло бы оказаться полезным. Однако, возможно, вам лучше погрузиться в настройки только из шаблонов, которым нужна эта переменная. В этом случае нет смысла передавать переменную во все шаблоны. Но если вы отправляете переменную в общий шаблон, такой как шаблон 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)
person un33k    schedule 11.12.2011
comment
Или вы можете использовать SITE_EXTRA_CONTEXT_DICT в finalware, чтобы сделать это за вас. - person un33k; 26.03.2016