from django.conf import settings




我可以通過Django中的模板訪問settings.py中的常量嗎? (10)

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")

我在settings.py中有一些我希望能夠從模板訪問的東西,但我無法弄清楚如何去做。 我已經嘗試過了

{{CONSTANT_NAME}}

但這似乎並不奏效。 這可能嗎?


用Django 2.0添加一個答案和完整的說明來創建一個可以解決這個問題的自定義模板標籤

在您的應用程序文件夾中,創建一個名為templatetags的文件夾。 在它中,創建__init__.pycustom_tags.py

custom_tags.py中創建一個自定義標記函數,該函數提供對設置常量中的任意鍵的訪問:

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

這個解決方案不適用於數組,但是如果你需要的話,你可能會在你的模板中放置很多邏輯。


如果使用基於類的視圖:

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

如果您使用django的內置通用視圖或在render_to_response快捷方式函數中傳遞上下文實例關鍵字參數,Django可以訪問模板的某些常用設置常量,例如settings.MEDIA_URL和一些語言設置。 以下是每種情況的示例:

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)

現在,您可以在模板上以{{ favorite_color }}訪問settings.FAVORITE_COLOR


如果有人像我這樣發現了這個問題,那麼我會發布我的解決方案,它在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 == True %}
... do something ...
{% else %}
... do other stuff ...
{% endif %}

請參閱Django的文檔,了解如何在此創建自定義模板標記: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/


如果這是您想要的每個請求和模板的值,則使用上下文處理器更合適。

就是這樣:

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

我喜歡Berislav的解決方案,因為在簡單的網站上,它是乾淨而有效的。 我不喜歡的是暴露所有設置常量。 所以我最終做的是這樣的:

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

這可以保護任何你沒有在模板中使用的常量,並且如果你想變得很花哨,你可以在設置中設置一個元組,並為不同的頁面,應用程序或區域創建多個模板標籤,根據需要組合本地元組和設置元組,然後執行列表理解以查看該值是否可接受。
我同意,在一個複雜的網站上,這有點簡單,但有一些值得在模板中普遍使用,這似乎很好。 感謝Berislav提出的最初創意!


我改進了一下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 ...符號的優點是,這使得通過簡單的{{my_fqdn}}可以輕鬆地在blocktrans塊中使用。


我發現這是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 }}';
    

退房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>




django-settings