テンプレートからアクセスできるようにしたいものが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
すべてのビューでこのコードを書く必要がないように注意してください。
それがすべてのリクエストとテンプレートに必要な値である場合は、コンテキストプロセッサを使用する方が適切です。
方法は次のとおりです。
作る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のデフォルト値が空ではないという事実についての回答にメモを追加することをお勧めします。そのため、既存のコードがそれらのデフォルトのコンテキストプロセッサによって設定された値のいずれかを使用する場合、それらを追加しない限り機能しません。リストに明示的に。
render
ショートカットを使用して、RequestContext
最も単純なアプローチは、単一のカスタムテンプレートタグであることがわかります。
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" %}
か?このユースケースでは、そもそもテンプレートで設定を使用できない理由を明らかにする必要があります。
templatetags
アプリ内に空の__init__.py
ファイルとこのコードを含むフォルダーをフォルダー内に作成settings.py
します。2)テンプレートに追加{% load settings %}
した新しいタグを使用します!
チェックアウト 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
これを行う別の方法は、設定から値を釣り上げることができるカスタムテンプレートタグを作成することです。
@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" %}
コンテキストプロセッサのフープを飛び越えることなく、任意のページに印刷する。
単純なサイトではクリーンで効果的であるため、ベリスラフのソリューションが好きです。私が気に入らないのは、すべての設定定数を公開することです。だから私がやったことはこれでした:
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: ...
'val' in ('val_first', 'second_val',)
はFalse
、ここでは部分文字列の問題はありません。
if
ステートメントでどのように使用できますか?DEBUG
値を確認したい
私はクリスデューの答え(あなた自身のタグを作成するため)を少し改善しました。
まず、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}}
です。
Django 2.0以降で、これを解決するカスタムテンプレートタグを作成するための完全な手順を含む回答を追加する
アプリのフォルダーで、templatetagsという名前のフォルダーを作成します。その中に__init__.pyとcustom_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" %}
このソリューションは配列では機能しませんが、必要な場合は、テンプレートで多くのロジックを使用する可能性があります。
注:よりクリーンでフェイルセーフなソリューションは、おそらく、必要な設定をすべてのテンプレートで使用可能なコンテキストに追加するカスタムコンテキストプロセッサを作成することです。これにより、誤ってテンプレートに機密設定を出力するリスクを軽減できます。
次のコードをこのファイルに追加します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.pyを確認できます)。
その後、任意のテンプレートコードで特定の設定を使用できます。例えば:
{% 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
。ハッカーはこの機能を悪用して、そのような情報をテンプレートに表示する可能性があります。
上記の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 %}
{% if settings_debug == True %}
あなたの提案に変更{% if settings_debug %}
クラスベースのビューを使用している場合:
#
# 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の両方が、設定で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 inquestionが未定義だった場合に備えて、デフォルト値を渡すことができるため、次のコードを使用します。
例: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)