Bir şablondan erişebilmek istediğim settings.py dosyasında bazı şeyler var, ancak nasıl yapılacağını anlayamıyorum. Zaten denedim
{{CONSTANT_NAME}}
ama bu işe yaramıyor gibi görünüyor. Mümkün mü?
Bir şablondan erişebilmek istediğim settings.py dosyasında bazı şeyler var, ancak nasıl yapılacağını anlayamıyorum. Zaten denedim
{{CONSTANT_NAME}}
ama bu işe yaramıyor gibi görünüyor. Mümkün mü?
Yanıtlar:
Django, settings.MEDIA_URL
genel görünümlerde yerleşik django kullanırsanız veya render_to_response
kısayol işlevinde bir bağlam örneği anahtar sözcüğü argümanı iletirseniz , şablona , dil ayarları gibi bazı, sık kullanılan ayar sabitlerine erişim sağlar . Her durum için bir örnek:
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 settings.MEDIA_URL
şablon tarafından kullanılabilen gibi sık kullanılan çeşitli ayarlar bulunur {{ MEDIA_URL }}
.
Ayarlardaki diğer sabitlere erişmek istiyorsanız, istediğiniz sabitleri paketinden çıkarın ve görünüm işlevinizde kullandığınız bağlam 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 settings.FAVORITE_COLOR
şablonunuza olarak erişebilirsiniz {{ favorite_color }}
.
django-settings-export
Bu kodu her görünümde yazma gereğini ortadan kaldırmak için bakın .
Bir içerik işlemcisi kullanarak her istek ve şablon için sahip olmak istediğiniz bir değerse kullanmak daha uygundur.
Bunu nasıl yapacağınız aşağıda açıklanmıştır:
context_processors.py
Uygulama dizininizde bir dosya oluşturun. Diyelim ki ADMIN_PREFIX_VALUE
her bağlamda değere sahip olmak istiyorum :
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}
bağlam işlemcinizi settings.py dosyanıza ekleyin :
TEMPLATES = [{
# whatever comes before
'OPTIONS': {
'context_processors': [
# whatever comes before
"your_app.context_processors.admin_media",
],
}
}]
RequestContext
Şablonunuza bağlam işlemcilerinizi eklemek için görünümünüzde kullanın . render
Kısayol otomatik olarak yapar:
from django.shortcuts import render
def my_view(request):
return render(request, "index.html")
ve son olarak, şablonunuzda:
...
<a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
...
context_process.py
hemen yanında benim için settings.py
dosya ve katma "context_processors.admin_media"
benim için TEMPLATE_CONTEXT_PROCESSORS
listede. Ayrıca, cevabınıza TEMPLATE_CONTEXT_PROCESSORS'ın varsayılan değerinin boş olmadığı hakkında bir not eklemek isteyebilirsiniz, bu nedenle mevcut herhangi bir kod bu varsayılan bağlam işlemcileri tarafından ayarlanan değerlerden herhangi birini kullanıyorsa, bunları geri eklemediğiniz sürece çalışmaz listeye ekleyin.
render
RequestContext'i açıkça dahil etmek zorunda kalmamak için kısayolu kullanabilirsiniz : docs.djangoproject.com/en/1.6/topics/http/shortcuts/#render
En basit yaklaşımı tek bir özel şablon etiketi olarak görüyorum :
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" %}
{% settings_value "DATABASES" %}
? Bu kullanım örneği, ayarların başlangıçta şablonlarda neden kullanılamadığını açıkça ortaya koymalıdır.
templatetags
uygulamanızın içinde boş bir __init__.py
dosya ve bu kodun settings.py
içinde olduğu gibi bu kodu içeren bir klasör oluşturmanız gerekir . 2) şablonunuza ekleyin {% load settings %}
ve ardından yeni etiketinizi kullanın!
Check out django-settings-export
(feragatname: Bu projenin yazarıyım).
Örneğin...
$ 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
değilrender_to_response
Bunu yapmanın başka bir yolu, değerleri ayarlardan çıkarmanıza izin verebilecek ö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))
Daha sonra şunları kullanabilirsiniz:
{% value_from_settings "FQDN" %}
bağlam-işlemci kasnaklarına atlamaksızın herhangi bir sayfaya yazdırmak.
Berislav'un çözümünü seviyorum, çünkü basit sitelerde temiz ve etkilidir. Ne sevmiyorum tüm ayarları sabit willy-nilly maruz olduğunu. Sonuçta 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, adlandırmadığınız sabitleri şablonda kullanımdan korur ve gerçekten süslü olmak istiyorsanız, ayarlarda bir grup oluşturabilir ve farklı sayfalar, uygulamalar veya alanlar için birden fazla şablon etiketi oluşturabilirsiniz ve yerel bir demet ile gerektiğinde ayar demetini birleştirin, ardından değerin kabul edilebilir olup olmadığını görmek için liste kavrayışı yapın.
Katılıyorum, karmaşık bir sitede, bu biraz basit, ancak şablonlarda evrensel olarak olması güzel değerler var ve bu iyi çalışıyor gibi görünüyor. Orijinal fikir için Berislav'a teşekkürler!
if name in ALLOWABLE_VALUES: ...
'val' in ('val_first', 'second_val',)
burada False
, alt dize sorunu yok.
if
ifadede nasıl kullanabilirim ? DEBUG
değeri kontrol etmek istiyorum
Chrisdew'in cevabını geliştirdim (kendi etiketi oluşturmak için) biraz.
İlk olarak, yourapp/templatetags/value_from_settings.py
kendi yeni etiketinizi tanımladığınız dosyayı oluşturun 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
Bu etiketi Şablonunuzda şu yolla kullanabilirsiniz:
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}
veya yoluyla
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}
as ...
İşaretin avantajı, bunun basit bir şekilde blocktrans
bloklarda kullanımını kolaylaştırmasıdır {{my_fqdn}}
.
Django 2.0+ ile bunu çözen özel bir şablon etiketi oluşturmak için eksiksiz talimatlar içeren bir cevap ekleme
Uygulama klasörünüzde, templatetags adlı bir klasör oluşturun . İçinde __init__.py ve custom_tags.py oluşturun :
Gelen custom_tags.py içinde keyfi bir anahtara erişim sağlayan özel bir etiket işlevi oluşturmak ayarları sabiti:
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 Django belgelerindeki basit etiketlerle ilgili bölümü okumanızı tavsiye ederim .
Ardından, bu dosyayı kullanacağınız herhangi bir şablona yükleyerek Django'yu bu (ve herhangi bir ek) özel etiketten haberdar etmeniz gerekir. Tıpkı yerleşik statik etiketi yüklemeniz gerektiği gibi:
{% load custom_tags %}
Yüklendiğinde, diğer tüm etiketler gibi kullanılabilir, sadece iade etmeniz gereken belirli ayarı sağlayın. Dolayısıyla, ayarlarınızda bir BUILD_VERSION değişkeni varsa:
{% get_setting "BUILD_VERSION" %}
Bu çözüm dizilerle çalışmaz, ancak ihtiyacınız varsa şablonlarınızda çok fazla mantık oluşturuyor olabilirsiniz.
Not: Daha temiz ve güvenli bir çözüm, ihtiyacınız olan ayarları tüm şablonların kullanabileceği bir bağlama eklediğiniz özel bir bağlam işlemcisi yapmak olabilir. Bu şekilde, şablonlarınızda hassas ayarların yanlışlıkla çıkma riskini azaltırsınız.
Bu kodu şu adlı bir dosyaya ekleyin context_processors.py
:
from django.conf import settings as django_settings
def settings(request):
return {
'settings': django_settings,
}
Ve sonra, ayarlarınız dosyasında gibi bir yol ekleyin 'speedy.core.base.context_processors.settings'
içinde (uygulama adı ve yolu ile) 'context_processors'
ayarlarındaTEMPLATES
.
(Örneğin, settings / base.py ve context_processors.py dosyalarını görebilirsiniz ).
Ardından, herhangi bir şablon kodunda belirli bir ayarı kullanabilirsiniz. Örneğin:
{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}
Güncelleme: Yukarıdaki kod, sizin gibi hassas bilgiler de dahil olmak üzere tüm ayarları şablonlara gösterir SECRET_KEY
. Bir bilgisayar korsanı bu tür bilgileri şablonlarda görüntülemek için bu özelliği kötüye kullanabilir. Şablonlara yalnızca belirli ayarları göstermek istiyorsanız, bunun yerine bu kodu kullanın:
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
. Bir bilgisayar korsanı, şablonlarda bu tür bilgileri görüntülemek için bu özelliği kötüye kullanabilir.
Yukarıdaki örnek bchhun'dan güzeldir, ancak bağlam sözlüğünüzü açıkça settings.py'den oluşturmanız gerekir. Aşağıda, content.py'nin tüm büyük harfli özniteliklerinden bağlam sözlüğünü otomatik olarak nasıl oluşturabileceğinize ilişkin SINAVSIZ bir örnek bulunmaktadır (re: "^ [A-Z0-9 _] + $").
Settings.py dosyasının 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',
...
)
Birisi bu soruyu benim yaptığım gibi bulursa, Django 2.0'da çalışan çözümümü gönderirim:
Bu etiket, şablonun değişkenine bazı settings.py değişken değeri atar:
Kullanımı: {% 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 %}
Özel şablon etiketlerinin nasıl oluşturulacağı konusundaki Django belgelerine bakın: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
{% if settings_debug %}
{% if settings_debug == True %}
Önerdiğiniz olarak değiştirildi{% if settings_debug %}
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 }}
Hem IanSR hem de bchhun, ayarlarda TEMPLATE_CONTEXT_PROCESSORS'ın geçersiz kılınmasını önerdi. Bu ayarın, varsayılanları yeniden ayarlamadan geçersiz kılarsanız bazı vidalı şeylere neden olabilecek bir varsayılanı olduğunu unutmayın. Varsayılan değerler, 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")
Bağlam ve şablon etiketlerini tek bir değişken üzerinde karşılaştırırsak, daha verimli 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çirmek mantıklı değildir. Ancak değişkeni base.html şablonu gibi ortak bir şablona gönderiyorsanız, her istekte base.html şablonu oluşturulduğundan fark etmez, bu nedenle her iki yöntemi de kullanabilirsiniz.
Şablon etiketleri seçeneğiyle gitmeye karar verirseniz , söz konusu değişkenin tanımsız olması durumunda, varsayılan bir değer geçirmenize izin verdiği için aşağıdaki kodu kullanın .
Ö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)