我可以从Django中的模板访问settings.py中的常量吗?

我在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) 

现在,您可以在模板上以{{ favorite_color }}访问settings.FAVORITE_COLOR

如果这是每个请求和模板的值,那么使用上下文处理器更合适。

就是这样:

  1. 在app目录中创build一个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> ... 

我发现最简单的方法是一个模板标签:

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

检查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> 

另一种方法是创build一个自定义的模板标签,它可以让你将设置中的值删除。

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

在任何页面上打印,而不用跳过上下文处理器环节。

我喜欢Berislav的解决scheme,因为在简单的网站上,它是干净和有效的。 我不喜欢的是暴露所有的设置常量,无所谓。 所以我最终做的是这样的:

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

这可以保护你没有在模板中使用的任何常量,如果你想变得很花哨,你可以在设置中设置一个元组,并为不同的页面,应用程序或区域创build多个模板标签,根据需要组合本地元组和设置元组,然后执行列表理解,以查看该值是否可接受。
我同意,在一个复杂的网站上,这有点简单,但是有一些值得在模板中普遍使用,这似乎很好。 感谢Berislav的原创主意!

我改进了一下chrisdew的答案 (创build自己的标签)。

首先,创build文件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块中使用。

从bchhun上面的例子是不错的,除了你需要显式地从settings.pybuild立你的上下文字典。 下面是一个UNTESTED示例,说明如何从settings.py(re:“^ [A-Z0-9 _] + $”)的所有大写属性自动构build上下文字典。

在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', ... ) 

如果使用基于类的视图:

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

IanSR和bchhun都build议在设置中覆盖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") 

如果我们要在一个variables上比较上下文和模板标签,那么知道更高效的选项可能是很好的。 但是,您最好只能从需要该variables的模板中进入设置。 在这种情况下,将variables传递到所有模板是没有意义的。 但是,如果您将variables发送到通用模板(如base.html模板),那么无需考虑base.html模板,因此您可以使用任一方法。

如果您决定使用模板标签选项,那么请使用以下代码,因为它允许您传递默认值,以防variables问题未定义。

例如:get_from_settings my_variable as my_context_value

例如: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) 

我发现这是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 }}';