web-dev-qa-db-ja.com

Djangoのテンプレートからsettings.pyの定数にアクセスできますか?

Settings.pyには、テンプレートからアクセスできるようにしたいものがいくつかありますが、その方法がわかりません。私はすでに試しました

{{CONSTANT_NAME}}

しかし、それはうまくいかないようです。これは可能ですか?

337
Paul Wicks

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 }}としてアクセスできます。

164
Prairiedogg

すべてのリクエストとテンプレートに必要な値である場合は、 コンテキストプロセッサ を使用する方が適切です。

方法は次のとおりです。

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

最も単純なアプローチは、単一のテンプレートタグです。

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" %}
236
Berislav Lopac

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>
89
Jakub

これを行う別の方法は、設定から値を取得できるカスタムテンプレートタグを作成することです。

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

コンテキストプロセッサフ​​ープをジャンプすることなく、任意のページに印刷します。

42
fadedbee

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

これにより、テンプレートで使用しないように名前を付けていない定数が保護されます。本当に凝りたい場合は、設定でタプルを設定し、さまざまなページ、アプリ、または領域に対して複数のテンプレートタグを作成し、必要に応じてローカルのタプルと設定のタプルを組み合わせてから、リストの内包表記を実行して、値が受け入れられるかどうかを確認します。
私は同意します。複雑なサイトでは、これは少し単純化されていますが、テンプレートで普遍的に持つ価値がある値があり、これはうまく機能しているようです。オリジナルのアイデアをくれたベリスラフに感謝します!

24
MontyThreeCard

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ブロックで簡単に使用できるようになることです。

11
pklaus

Django 2.0 +を使用して、これを解決するカスタムテンプレートタグを作成するための完全な手順を含む回答を追加する

App-folderで、templatetagsというフォルダーを作成します。その中で、__ init __。pycustom_tags.pyを作成します:

Custom tags folder structure

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

このソリューションは配列では機能しませんが、必要な場合はテンプレートに多くのロジックを入れる必要があります。

8

上記の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',
...
)
7
IanSR

私がしたように誰かがこの質問を見つけたら、Django 2.0で動作するソリューションを投稿します。

このタグは、いくつかのsettings.py変数値をテンプレートの変数に割り当てます。

使用法:{% get_settings_value template_var "SETTINGS_VAR" %}

app/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/

5
NullIsNot0

このコードを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 )。

4
Uri

クラスベースのビューを使用している場合:

#
# 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 }}
4
Bill Paetzke

これが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 }}';
    
1
Michael

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

単一の変数でコンテキストタグとテンプレートタグを比較する場合、より効率的なオプションを知ることは有益です。ただし、その変数を必要とするテンプレートからのみ設定に浸ることをお勧めします。その場合、変数をすべてのテンプレートに渡すことは意味がありません。しかし、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)
0
un33k