Settings.pyには、テンプレートからアクセスできるようにしたいものがいくつかありますが、その方法がわかりません。私はすでに試しました
{{CONSTANT_NAME}}
しかし、それはうまくいかないようです。これは可能ですか?
Djangoは、Djangoの組み込みの汎用ビューを使用する場合、またはsettings.MEDIA_URL
ショートカット関数でコンテキストインスタンスキーワード引数を渡す場合、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 }}
としてアクセスできます。
すべてのリクエストとテンプレートに必要な値である場合は、 コンテキストプロセッサ を使用する方が適切です。
方法は次のとおりです。
アプリディレクトリに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>
...
最も単純なアプローチは、単一のテンプレートタグです。
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
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
'Django_settings_export.settings_export',
],
},
},
]
MY_CHEESE = 'Camembert';
SETTINGS_EXPORT = [
'MY_CHEESE',
]
<script>var MY_CHEESE = '{{ settings.MY_CHEESE }}';</script>
これを行う別の方法は、設定から値を取得できるカスタムテンプレートタグを作成することです。
@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のソリューションが好きです。シンプルなサイトではクリーンで効果的だからです。私が気に入らないのは、すべての設定定数を故意に公開することです。だから私がやったことはこれでした:
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" %}
これにより、テンプレートで使用しないように名前を付けていない定数が保護されます。本当に凝りたい場合は、設定でタプルを設定し、さまざまなページ、アプリ、または領域に対して複数のテンプレートタグを作成し、必要に応じてローカルのタプルと設定のタプルを組み合わせてから、リストの内包表記を実行して、値が受け入れられるかどうかを確認します。
私は同意します。複雑なサイトでは、これは少し単純化されていますが、テンプレートで普遍的に持つ価値がある値があり、これはうまく機能しているようです。オリジナルのアイデアをくれたベリスラフに感謝します!
chrisdew's answer (独自のタグを作成するため)を少し改善しました。
最初に、独自の新しいタグ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 2.0 +を使用して、これを解決するカスタムテンプレートタグを作成するための完全な手順を含む回答を追加する
App-folderで、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" %}
このソリューションは配列では機能しませんが、必要な場合はテンプレートに多くのロジックを入れる必要があります。
上記のbchhunの例は、settings.pyからコンテキストディクショナリを明示的に構築する必要があることを除いて、ニースです。以下は、settings.pyのすべての大文字属性からコンテキストディクショナリを自動構築できる方法の未テストの例です(「^ [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/
このコードをcontext_processors.py
というファイルに追加します。
from Django.conf import settings as Django_settings
def settings(request):
return {
'settings': Django_settings,
}
そして、設定ファイルで、TEMPLATES
の'speedy.core.base.context_processors.settings'
設定に'context_processors'
などのパスを(アプリ名とパスとともに)含めます。
(たとえば https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/settings/base.py および https:/ /github.com/speedy-net/speedy-net/blob/staging/speedy/core/base/context_processors.py )。
クラスベースのビューを使用している場合:
#
# 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 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テンプレートはすべてのリクエストでレンダリングされるため、どちらの方法でも使用できます。
テンプレートタグオプションを使用する場合、変数in-questionが未定義の場合に備えてdefault値を渡すことができるため、次のコードを使用します。
例: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)