Saya memiliki beberapa hal di settings.py yang ingin saya akses dari templat, tetapi saya tidak tahu cara melakukannya. Saya sudah mencoba
{{CONSTANT_NAME}}
tapi itu sepertinya tidak berhasil. Apakah ini mungkin?
Saya memiliki beberapa hal di settings.py yang ingin saya akses dari templat, tetapi saya tidak tahu cara melakukannya. Saya sudah mencoba
{{CONSTANT_NAME}}
tapi itu sepertinya tidak berhasil. Apakah ini mungkin?
Jawaban:
Django menyediakan akses ke konstanta pengaturan tertentu yang sering digunakan untuk template seperti settings.MEDIA_URL
dan beberapa pengaturan bahasa jika Anda menggunakan Django bawaan dalam pandangan umum atau meneruskan dalam konteks contoh kata kunci argumen dalam render_to_response
fungsi pintas. Berikut ini adalah contoh dari setiap kasus:
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))
Tampilan ini akan memiliki beberapa pengaturan yang sering digunakan seperti settings.MEDIA_URL
tersedia untuk template seperti {{ MEDIA_URL }}
, dll.
Jika Anda mencari akses ke konstanta lain di pengaturan, maka cukup buka konstanta yang Anda inginkan dan tambahkan mereka ke kamus konteks yang Anda gunakan dalam fungsi tampilan Anda, seperti:
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)
Sekarang Anda dapat mengakses settings.FAVORITE_COLOR
pada templat Anda sebagai {{ favorite_color }}
.
django-settings-export
untuk menghindari kebutuhan untuk menulis kode ini di setiap tampilan.
Jika itu nilai yang ingin Anda miliki untuk setiap permintaan & templat, menggunakan pengolah konteks lebih tepat.
Begini caranya:
Buat context_processors.py
file di direktori aplikasi Anda. Katakanlah saya ingin memiliki ADMIN_PREFIX_VALUE
nilai dalam setiap konteks:
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}
tambahkan pemroses konteks Anda ke file settings.py Anda :
TEMPLATES = [{
# whatever comes before
'OPTIONS': {
'context_processors': [
# whatever comes before
"your_app.context_processors.admin_media",
],
}
}]
Gunakan RequestContext
dalam tampilan Anda untuk menambahkan pemroses konteks Anda dalam templat Anda. Cara render
pintas melakukan ini secara otomatis:
from django.shortcuts import render
def my_view(request):
return render(request, "index.html")
dan akhirnya, di templat Anda:
...
<a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
...
context_process.py
tepat di sebelah settings.py
file saya dan ditambahkan "context_processors.admin_media"
ke TEMPLATE_CONTEXT_PROCESSORS
daftar saya . Juga, Anda mungkin ingin menambahkan catatan dalam jawaban Anda tentang fakta bahwa nilai default TEMPLATE_CONTEXT_PROCESSORS tidak kosong, jadi jika ada kode yang menggunakan nilai apa pun yang ditetapkan oleh pengolah konteks default, mereka tidak akan berfungsi kecuali jika Anda menambahkannya kembali ke daftar secara eksplisit.
render
pintasan untuk menghindari keharusan secara eksplisit menyertakan RequestContext: docs.djangoproject.com/en/1.6/topics/http/shortcuts/#render
Saya menemukan pendekatan paling sederhana menjadi tag templat tunggal :
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, "")
Pemakaian:
{% settings_value "LANGUAGE_CODE" %}
{% settings_value "DATABASES" %}
:? Kasing ini harus menjelaskan mengapa pengaturan tidak tersedia di template untuk memulai.
templatetags
folder di dalam aplikasi Anda dengan __init__.py
file kosong dan kode ini sebagai settings.py
di dalam folder itu. 2) di templat yang Anda tambahkan {% load settings %}
dan gunakan tag baru Anda!
Lihat django-settings-export
(penafian: Saya penulis proyek ini).
Sebagai contoh...
$ 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
dan tidakrender_to_response
Cara lain untuk melakukan ini adalah dengan membuat tag templat kustom yang dapat membuat Anda mendapatkan nilai dari pengaturan.
@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))
Anda kemudian dapat menggunakan:
{% value_from_settings "FQDN" %}
untuk mencetaknya di halaman mana saja, tanpa melewati konteks-prosesor lingkaran.
Saya suka solusi Berislav, karena di situs sederhana, ini bersih dan efektif. Apa yang saya TIDAK suka adalah mengekspos semua konstanta pengaturan mau tak mau. Jadi yang akhirnya saya lakukan adalah ini:
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 ''
Pemakaian:
{% settings_value "CONSTANT_NAME_1" %}
Ini melindungi konstanta yang belum Anda sebutkan namanya untuk digunakan dalam template, dan jika Anda ingin benar-benar mewah, Anda bisa mengatur tuple di pengaturan, dan membuat lebih dari satu tag template untuk halaman, aplikasi atau area yang berbeda, dan cukup menggabungkan tuple lokal dengan tuple pengaturan sesuai kebutuhan, kemudian lakukan pemahaman daftar untuk melihat apakah nilainya dapat diterima.
Saya setuju, di situs yang kompleks, ini agak sederhana, tetapi ada nilai-nilai yang akan menyenangkan untuk dimiliki secara universal di templat, dan ini tampaknya berfungsi dengan baik. Terima kasih kepada Berislav untuk ide aslinya!
if name in ALLOWABLE_VALUES: ...
'val' in ('val_first', 'second_val',)
adalah False
, tidak ada substring masalah di sini.
if
pernyataan? saya ingin memeriksa DEBUG
nilainya
Saya sedikit memperbaiki jawaban chrisdew (untuk membuat tag Anda sendiri).
Pertama, buat file yourapp/templatetags/value_from_settings.py
tempat Anda mendefinisikan tag baru Anda sendiri 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
Anda dapat menggunakan tag ini di Templat Anda melalui:
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}
atau via
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}
Keuntungan dari as ...
notasi adalah ini membuatnya mudah digunakan dalam blocktrans
blok melalui sederhana {{my_fqdn}}
.
Menambahkan jawaban dengan instruksi lengkap untuk membuat tag templat kustom yang menyelesaikan ini, dengan Django 2.0+
Di folder aplikasi Anda, buat folder bernama templatetags . Di dalamnya, buat __init__.py dan custom_tags.py :
Di custom_tags.py buat fungsi tag khusus yang menyediakan akses ke kunci sewenang-wenang di konstanta pengaturan :
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def get_setting(name):
return getattr(settings, name, "")
Untuk memahami kode ini saya sarankan membaca bagian tentang tag sederhana di dokumen Django.
Kemudian, Anda perlu membuat Django mengetahui tag kustom ini (dan tambahan apa pun) dengan memuat file ini dalam templat apa pun di mana Anda akan menggunakannya. Sama seperti Anda perlu memuat tag statis bawaan:
{% load custom_tags %}
Dengan itu dimuat dapat digunakan sama seperti tag lain, cukup berikan pengaturan khusus yang Anda butuhkan kembali. Jadi, jika Anda memiliki variabel BUILD_VERSION di pengaturan Anda:
{% get_setting "BUILD_VERSION" %}
Solusi ini tidak akan bekerja dengan array, tetapi jika Anda perlu, Anda mungkin menempatkan banyak logika di template Anda.
Catatan: Solusi yang lebih bersih dan gagal mungkin akan membuat pengolah konteks khusus tempat Anda menambahkan pengaturan yang Anda perlukan ke konteks yang tersedia untuk semua templat. Dengan cara ini Anda mengurangi risiko menghasilkan pengaturan sensitif dalam template Anda secara tidak sengaja.
Tambahkan kode ini ke file bernama context_processors.py
:
from django.conf import settings as django_settings
def settings(request):
return {
'settings': django_settings,
}
Dan kemudian, dalam file pengaturan Anda, sertakan jalur seperti 'speedy.core.base.context_processors.settings'
(dengan nama aplikasi dan jalur Anda) dalam 'context_processors'
pengaturan diTEMPLATES
.
(Anda dapat melihat misalnya pengaturan / base.py dan context_processors.py ).
Kemudian Anda dapat menggunakan pengaturan khusus dalam kode template apa pun. Sebagai contoh:
{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}
Pembaruan: Kode di atas memperlihatkan semua pengaturan ke template, termasuk informasi sensitif seperti Anda SECRET_KEY
. Seorang hacker mungkin menyalahgunakan fitur ini untuk menampilkan informasi seperti itu di template. Jika Anda hanya ingin mengekspos pengaturan spesifik ke template, gunakan kode ini sebagai gantinya:
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
. Seorang hacker mungkin menyalahgunakan fitur ini untuk menampilkan informasi seperti itu di templat.
Contoh di atas dari bchhun bagus kecuali bahwa Anda perlu membangun kamus konteks Anda secara eksplisit dari settings.py. Di bawah ini adalah contoh TERTULIS tentang bagaimana Anda dapat membangun-otomatis kamus konteks dari semua atribut huruf besar dari settings.py (re: "^ [A-Z0-9 _] + $").
Di akhir 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',
...
)
Jika seseorang menemukan pertanyaan ini seperti yang saya lakukan, maka saya akan memposting solusi saya yang berfungsi pada Django 2.0:
Tag ini memberikan beberapa nilai variabel settings.py ke variabel templat:
Pemakaian: {% 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 %}
Lihat dokumentasi Django cara membuat tag templat khusus di sini: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
{% if settings_debug %}
{% if settings_debug == True %}
sesuai saran Anda{% if settings_debug %}
Jika menggunakan tampilan berbasis kelas:
#
# 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 dan bchhun menyarankan untuk mengganti TEMPLATE_CONTEXT_PROCESSORS di pengaturan. Perlu diketahui bahwa pengaturan ini memiliki standar yang dapat menyebabkan beberapa hal kacau jika Anda menimpanya tanpa mengatur ulang default. Defaultnya juga telah berubah di versi terbaru Django.
https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors
TEMPLATE_CONTEXT_PROCESSORS default:
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")
Jika kita membandingkan tag konteks vs template pada satu variabel, maka mengetahui opsi yang lebih efisien bisa jadi buatan. Namun, Anda mungkin lebih baik mencelupkan ke pengaturan hanya dari template yang membutuhkan variabel itu. Dalam hal ini, tidak masuk akal untuk meneruskan variabel ke semua templat. Tetapi jika Anda mengirim variabel ke templat umum seperti templat base.html, Maka itu tidak masalah karena templat base.html diberikan pada setiap permintaan, sehingga Anda dapat menggunakan salah satu metode.
Jika Anda memutuskan untuk pergi dengan opsi tag template, maka gunakan kode berikut karena memungkinkan Anda untuk melewati default nilai , kalau-kalau variabel yang dipertanyakan tidak ditentukan.
Contoh: get_from_settings my_variable sebagai my_context_value
Contoh: get_from_settings my_variable my_default sebagai 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)