it-swarm.dev

Settings.py'daki sabitlere Django'daki şablonlardan erişebilir miyim?

Settings.py'da şablondan erişebilmek istediğim bazı şeyler var, ancak nasıl yapılacağını çözemiyorum. Çoktan denedim

{{CONSTANT_NAME}}

ama bu işe yaramadı. Mümkün mü?

342
Paul Wicks

Django, genel görünümlerde yerleşik olarak kullanıyorsanız veya bir bağlam örneği anahtar sözcük değişkenini settings.MEDIA_URL içinde geçirirseniz, şablona render_to_response ve bazı dil ayarları gibi belirli, sık kullanılan ayar sabitlerine erişim sağlar. kısayol işlevi. İşte her durumun bir örneği:

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

Bu görünümlerin her ikisinde de şablona settings.MEDIA_URL, vb. Gibi mevcut {{ MEDIA_URL }} gibi birçok sık kullanılan ayar olacaktır.

Ayarlardaki diğer sabitlere erişim arıyorsanız, istediğiniz sabitleri açın ve görünüm işlevinizde kullandığınız içerik sözlüğüne ekleyin:

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)

Artık şablonunuzdaki settings.FAVORITE_COLOR öğesine {{ favorite_color }} olarak erişebilirsiniz.

166
Prairiedogg

Her istek ve şablon için sahip olmak istediğiniz bir değer ise, bağlam işlemci kullanmak daha uygundur.

İşte nasıl:

  1. Uygulama dizininizde bir context_processors.py dosyası oluşturun. Her bağlamda ADMIN_PREFIX_VALUE değerine sahip olmak istediğimi varsayalım:

    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. içerik işlemcinizi settings.py dosyanıza ekleyin:

    TEMPLATES = [{
        # whatever comes before
        'OPTIONS': {
            'context_processors': [
                # whatever comes before
                "your_app.context_processors.admin_media",
            ],
        }
    }]
    
  3. İçerik işlemcilerinizi şablonunuza eklemek için görünümünüzde RequestContext kullanın. render shortcut bunu otomatik olarak yapar:

    from Django.shortcuts import render
    
    def my_view(request):
        return render(request, "index.html")
    
  4. ve son olarak, şablonunuzda:

    ...
    <a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
    ...
    
409
bchhun

En basit yaklaşımı tek bir şablon etiketi olarak buluyorum:

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

Kullanımı:

{% settings_value "LANGUAGE_CODE" %}
240
Berislav Lopac

Check out Django-settings-export (sorumluluk reddi: Bu projenin yazarıyım).

Örneğin...

_$ 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

Bunu yapmanın başka bir yolu da, ayarlardan değer çıkarmanızı sağlayan özel bir şablon etiketi oluşturmaktır.

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

Sonra kullanabilirsiniz:

{% value_from_settings "FQDN" %}

bağlam işlemci çemberlerine atlamaksızın herhangi bir sayfaya yazdırmak için.

42
fadedbee

Berislav'ın çözümünü seviyorum, çünkü basit sitelerde temiz ve etkili. Sevmediğim tüm ayar sabitlerini nezaketle göstermek. Öyleyse yaptığım şey şuydu:

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

Kullanımı:

{% settings_value "CONSTANT_NAME_1" %}

Bu, şablonda kullanmak istemediğiniz sabitleri korur ve gerçekten fantezi almak istiyorsanız, ayarlarda bir Tuple ayarlayabilir ve farklı sayfalar, uygulamalar veya alanlar için birden fazla şablon etiketi oluşturabilir ve basitçe Yerel bir Tuple'ı gerektiği gibi Tuple ayarları ile birleştirin, ardından değerin kabul edilebilir olup olmadığını görmek için listeyi kavrayın.
Katılıyorum, karmaşık bir sitede, bu biraz basit, ancak evrensel olarak şablonlarda olması güzel olacak değerler var ve bu çok iyi çalışıyor gibi görünüyor. Özgün fikir için Berislav'a teşekkürler!

24
MontyThreeCard

İyileştirdim chrisdew'in cevabı (kendi etiketinizi oluşturmak için) biraz.

İlk önce, kendi yeni etiketinizi yourapp/templatetags/value_from_settings.py tanımladığınız value_from_settings dosyasını oluşturun:

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

Bu etiketi Şablonunuzda kullanarak:

{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}

veya via

{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}

as ... gösteriminin avantajı, bunun basit bir {{my_fqdn}} ile blocktrans bloklarda kullanılmasını kolaylaştırmasıdır.

11
pklaus

Bunu çözen özel bir şablon etiketi oluşturmak için gereken talimatları içeren bir cevap ekleme, Django 2.0 +

Uygulama klasörünüzde, templatetags adlı bir klasör oluşturun. İçinde, __ init __. Py ve custom_tags.py oluşturun:

Custom tags folder structure

custom_tags.py içinde ayarlarında isteğe bağlı bir tuşa erişim sağlayan özel bir etiket işlevi oluşturun sabit:

from Django import template
from Django.conf import settings

register = template.Library()

@register.simple_tag
def get_setting(name):
    return getattr(settings, name, "")

Bu kodu anlamak için okumanızı tavsiye ederim basit etiketlerle ilgili bölüm Django docs.

Ardından, bu dosyayı kullanacağınız herhangi bir şablona yükleyerek bu [ve diğer] özel etiketin Django farkında olmasını sağlamanız gerekir. Yerleşik statik etiketi yüklemeniz gerektiği gibi:

{% load custom_tags %}

Yüklendiğinde, başka herhangi bir etiket gibi kullanılabilir, sadece döndürmeniz gereken belirli ayarları sağlayın. Bu nedenle, ayarlarınızda bir BUILD_VERSION değişkeni varsa:

{% get_setting "BUILD_VERSION" %}

Bu çözüm dizilerle çalışmaz, ancak ihtiyacınız olursa şablonlarınızda çok fazla mantık kullanıyor olabilirsiniz.

9

Bchhun'dan yukarıdaki örnek, bağlam sözlüğünüzü settings.py'den açıkça oluşturmanız gerekmesi dışında, Nice'tir. Aşağıda, settings.py (re: "^ [A-Z0-9 _] + $") bağlam sözlüklerini otomatik olarak nasıl oluşturacağınıza dair UNTESTED örneği verilmiştir.

Settings.py'nin sonunda:

_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

Birisi bu soruyu benim gibi bulursa, Django 2.0 üzerinde çalışan çözümümü göndereceğim:

Bu etiket, şablon değişkenine bazı settings.py değişken değeri atar:

Kullanım: {% get_settings_value template_var "SETTINGS_VAR" %}

uygulamanın/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)

Şablonunuz:

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

Burada özel şablon etiketlerinin nasıl oluşturulduğunu Django'nun belgelerine bakın: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/

5
NullIsNot0

Bu kodu context_processors.py adlı bir dosyaya ekleyin:

from Django.conf import settings as Django_settings


def settings(request):
    return {
        'settings': Django_settings,
    }

Ardından, ayarlar dosyanızda, 'speedy.core.base.context_processors.settings' ayarlarında TEMPLATES öğesindeki 'context_processors' ayarlarına bir yol ekleyin (uygulama adınız ve yolunuzla birlikte).

(Örneğin görebilirsiniz https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/settings/base.py ve https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/base/context_processors.py ).

4
Uri

Sınıf tabanlı bir görünüm kullanıyorsanız:

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

Bunu Django 1.3 için en basit yaklaşım olarak buldum:

  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

Hem IanSR hem de bchhun ayarlarda TEMPLATE_CONTEXT_PROCESSORS öğesinin geçersiz kılınmasını önerdi. Varsayılanları yeniden ayarlamadan geçersiz kıldığınızda, bu ayarın bazı kötü şeylere neden olabilecek bir varsayılanının olduğunu unutmayın. Varsayılanlar, Django'nun son sürümlerinde de değişmiştir.

https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors

Varsayılan 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

Bağlam ve şablon etiketlerini tek bir değişkende karşılaştırırsak, o zaman daha verimli olan seçeneği bilmek yapay olabilir. Ancak, yalnızca bu değişkene ihtiyaç duyan şablonlardan ayarlara dalmak daha iyi olabilir. Bu durumda, değişkeni tüm şablonlara geçirmenin bir anlamı yoktur. Ancak değişkeni, base.html şablonu gibi ortak bir şablona gönderiyorsanız, o zaman her istek için base.html şablonunun işlenmesi önemli olmaz, bu nedenle her iki yöntemi de kullanabilirsiniz.

Eğer şablon etiketleri seçeneğiyle gitmeye karar verirseniz, aşağıdaki kodu kullanarak söz konusu değişkenin tanımsız olması durumunda, varsayılan değerini geçmenize izin verir.

Örnek: get_from_settings my_variable olarak my_context_value

Örnek: get_from_settings my_variable my_default olarak 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