Ich habe einige Einstellungen in settings.py, auf die ich über eine Vorlage zugreifen möchte, aber ich kann nicht herausfinden, wie das geht. Ich habe es schon versucht
{{CONSTANT_NAME}}
aber das scheint nicht zu funktionieren. Ist das möglich?
Ich habe einige Einstellungen in settings.py, auf die ich über eine Vorlage zugreifen möchte, aber ich kann nicht herausfinden, wie das geht. Ich habe es schon versucht
{{CONSTANT_NAME}}
aber das scheint nicht zu funktionieren. Ist das möglich?
Antworten:
Django bietet Zugriff auf bestimmte, häufig verwendete Einstellungskonstanten für die Vorlage, z. B. settings.MEDIA_URL
und einige der Spracheinstellungen, wenn Sie die in Django integrierten generischen Ansichten verwenden oder ein Schlüsselwortargument für eine Kontextinstanz in der render_to_response
Verknüpfungsfunktion übergeben. Hier ist ein Beispiel für jeden Fall:
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))
Diese Ansichten verfügen beide über mehrere häufig verwendete Einstellungen, wie settings.MEDIA_URL
sie für die Vorlage verfügbar sind {{ MEDIA_URL }}
, usw.
Wenn Sie in den Einstellungen nach Zugriff auf andere Konstanten suchen, entpacken Sie einfach die gewünschten Konstanten und fügen Sie sie dem Kontextwörterbuch hinzu, das Sie in Ihrer Ansichtsfunktion verwenden:
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)
Jetzt können Sie settings.FAVORITE_COLOR
auf Ihre Vorlage als zugreifen {{ favorite_color }}
.
django-settings-export
, um zu vermeiden, dass dieser Code in jeder Ansicht geschrieben werden muss.
Wenn es sich um einen Wert handelt, den Sie für jede Anforderung und Vorlage haben möchten, ist die Verwendung eines Kontextprozessors besser geeignet.
Hier ist wie:
Erstellen Sie eine context_processors.py
Datei in Ihrem App-Verzeichnis. Angenommen, ich möchte den ADMIN_PREFIX_VALUE
Wert in jedem Kontext haben:
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}
Fügen Sie Ihren Kontextprozessor zu Ihrer Datei settings.py hinzu :
TEMPLATES = [{
# whatever comes before
'OPTIONS': {
'context_processors': [
# whatever comes before
"your_app.context_processors.admin_media",
],
}
}]
Verwenden Sie RequestContext
in Ihrer Ansicht, um Ihre Kontextprozessoren zu Ihrer Vorlage hinzuzufügen. Die render
Verknüpfung führt dies automatisch aus:
from django.shortcuts import render
def my_view(request):
return render(request, "index.html")
und schließlich in Ihrer Vorlage:
...
<a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
...
context_process.py
direkt neben meine settings.py
Datei gesetzt und "context_processors.admin_media"
zu meiner TEMPLATE_CONTEXT_PROCESSORS
Liste hinzugefügt . Möglicherweise möchten Sie Ihrer Antwort auch einen Hinweis hinzufügen, dass der Standardwert von TEMPLATE_CONTEXT_PROCESSORS nicht leer ist. Wenn also ein vorhandener Code einen der von diesen Standardkontextprozessoren festgelegten Werte verwendet, funktionieren diese nur, wenn Sie sie wieder hinzufügen explizit zur Liste.
render
Verknüpfung verwenden, um zu vermeiden, dass RequestContext explizit eingeschlossen werden muss: docs.djangoproject.com/de/1.6/topics/http/shortcuts/#render
Ich finde, der einfachste Ansatz ist ein einzelnes benutzerdefiniertes Vorlagen-Tag :
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, "")
Verwendungszweck:
{% settings_value "LANGUAGE_CODE" %}
{% settings_value "DATABASES" %}
? Dieser Anwendungsfall sollte deutlich machen, warum Einstellungen in Vorlagen zunächst nicht verfügbar sind.
templatetags
Ordner in Ihrer App mit einer leeren __init__.py
Datei und diesem Code wie settings.py
in diesem Ordner erstellen . 2) In Ihrer Vorlage fügen Sie {% load settings %}
Ihr neues Tag hinzu und verwenden es dann!
Check out django-settings-export
(Haftungsausschluss: Ich bin der Autor dieses Projekts).
Zum Beispiel...
$ 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
und nichtrender_to_response
Eine andere Möglichkeit, dies zu tun, besteht darin, ein benutzerdefiniertes Vorlagen-Tag zu erstellen, mit dem Sie Werte aus den Einstellungen herausfischen können.
@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))
Sie können dann verwenden:
{% value_from_settings "FQDN" %}
um es auf einer beliebigen Seite zu drucken, ohne durch Kontextprozessor-Rahmen zu springen.
Ich mag Berislavs Lösung, weil sie auf einfachen Websites sauber und effektiv ist. Was ich NICHT mag, ist, alle Einstellungskonstanten wohl oder übel freizulegen. Am Ende habe ich also Folgendes gemacht:
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 ''
Verwendungszweck:
{% settings_value "CONSTANT_NAME_1" %}
Dies schützt alle Konstanten, die Sie nicht benannt haben, vor der Verwendung in der Vorlage. Wenn Sie wirklich ausgefallen sein möchten, können Sie in den Einstellungen ein Tupel festlegen und einfach mehr als ein Vorlagen-Tag für verschiedene Seiten, Apps oder Bereiche erstellen Kombinieren Sie nach Bedarf ein lokales Tupel mit dem Einstellungstupel und führen Sie dann das Listenverständnis durch, um festzustellen, ob der Wert akzeptabel ist.
Ich bin damit einverstanden, dass dies auf einer komplexen Site etwas simpel ist, aber es gibt Werte, die universell in Vorlagen zu finden wären, und dies scheint gut zu funktionieren. Danke an Berislav für die ursprüngliche Idee!
if name in ALLOWABLE_VALUES: ...
'val' in ('val_first', 'second_val',)
ist False
, nicht hier String Problem.
if
Anweisung verwenden? Ich möchte den DEBUG
Wert überprüfen
Ich habe die Antwort von chrisdew verbessert (um ein eigenes Tag zu erstellen) ein wenig .
Erstellen Sie zunächst die Datei, yourapp/templatetags/value_from_settings.py
in der Sie Ihr eigenes neues Tag definieren 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
Sie können dieses Tag in Ihrer Vorlage verwenden über:
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}
oder über
{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}
Der Vorteil der as ...
Notation ist, dass dies die Verwendung in blocktrans
Blöcken über eine einfache macht {{my_fqdn}}
.
Hinzufügen einer Antwort mit vollständigen Anweisungen zum Erstellen eines benutzerdefinierten Vorlagen-Tags, das dies mit Django 2.0+ löst
Erstellen Sie in Ihrem App-Ordner einen Ordner namens templatetags . Erstellen Sie darin __init__.py und custom_tags.py :
Im custom_tags.py eine benutzerdefinierten Tag - Funktion erstellen, die den Zugriff auf eine beliebige Taste in der bietet Einstellungen konstant:
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def get_setting(name):
return getattr(settings, name, "")
Um diesen Code zu verstehen, empfehle ich, den Abschnitt über einfache Tags in den Django-Dokumenten zu lesen .
Anschließend müssen Sie Django auf dieses (und jedes zusätzliche) benutzerdefinierte Tag aufmerksam machen, indem Sie diese Datei in eine beliebige Vorlage laden, in der Sie sie verwenden möchten. Genau wie Sie das eingebaute statische Tag laden müssen:
{% load custom_tags %}
Wenn es geladen ist, kann es wie jedes andere Tag verwendet werden. Geben Sie einfach die spezifische Einstellung an, die Sie zurückgeben möchten. Wenn Sie also eine BUILD_VERSION-Variable in Ihren Einstellungen haben:
{% get_setting "BUILD_VERSION" %}
Diese Lösung funktioniert nicht mit Arrays, aber wenn Sie dies benötigen, setzen Sie möglicherweise zu viel Logik in Ihre Vorlagen ein.
Hinweis: Eine sauberere und ausfallsichere Lösung besteht wahrscheinlich darin, einen benutzerdefinierten Kontextprozessor bereitzustellen, in dem Sie die erforderlichen Einstellungen zu einem Kontext hinzufügen, der allen Vorlagen zur Verfügung steht. Auf diese Weise verringern Sie das Risiko, versehentlich vertrauliche Einstellungen in Ihren Vorlagen auszugeben.
Fügen Sie diesen Code einer Datei mit dem Namen hinzu context_processors.py
:
from django.conf import settings as django_settings
def settings(request):
return {
'settings': django_settings,
}
Fügen Sie dann in Ihre Einstellungsdatei einen Pfad wie 'speedy.core.base.context_processors.settings'
(mit Ihrem App-Namen und Pfad) in die 'context_processors'
Einstellungen in ein TEMPLATES
.
(Sie können zum Beispiel settings / base.py und context_processors.py sehen ).
Anschließend können Sie die spezifische Einstellung in einem beliebigen Vorlagencode verwenden. Zum Beispiel:
{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}
Update: Der obige Code macht alle Einstellungen für Vorlagen verfügbar, einschließlich vertraulicher Informationen wie Ihrer SECRET_KEY
. Ein Hacker könnte diese Funktion missbrauchen, um solche Informationen in den Vorlagen anzuzeigen. Wenn Sie nur bestimmte Einstellungen für die Vorlagen verfügbar machen möchten, verwenden Sie stattdessen diesen Code:
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
. Ein Hacker könnte diese Funktion missbrauchen, um solche Informationen in den Vorlagen anzuzeigen.
Das obige Beispiel von bchhun ist nett, außer dass Sie Ihr Kontextwörterbuch explizit aus settings.py erstellen müssen. Unten finden Sie ein UNTESTED-Beispiel, wie Sie das Kontextwörterbuch automatisch aus allen Großbuchstabenattributen von settings.py erstellen können (bezüglich: "^ [A-Z0-9 _] + $").
Am Ende von 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',
...
)
Wenn jemand diese Frage so findet wie ich, werde ich meine Lösung veröffentlichen, die auf Django 2.0 funktioniert:
Dieses Tag weist der Variablen der Vorlage einige Werte für die Variablen settings.py zu:
Verwendungszweck: {% 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 %}
Weitere Informationen zum Erstellen benutzerdefinierter Vorlagen-Tags finden Sie in der Dokumentation von Django: https://docs.djangoproject.com/de/2.0/howto/custom-template-tags/
{% if settings_debug %}
{% if settings_debug == True %}
zu Ihrem Vorschlag{% if settings_debug %}
Bei Verwendung einer klassenbasierten Ansicht:
#
# 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 }}
Sowohl IanSR als auch bchhun schlugen vor, TEMPLATE_CONTEXT_PROCESSORS in den Einstellungen zu überschreiben. Beachten Sie, dass diese Einstellung eine Standardeinstellung hat, die einige Probleme verursachen kann, wenn Sie sie überschreiben, ohne die Standardeinstellungen neu festzulegen. Die Standardeinstellungen haben sich auch in den letzten Versionen von Django geändert.
https://docs.djangoproject.com/de/1.3/ref/settings/#template-context-processors
Die Standardwerte für 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")
Wenn wir Kontext- und Vorlagen-Tags für eine einzelne Variable vergleichen, könnte es von Vorteil sein, die effizientere Option zu kennen. Es ist jedoch möglicherweise besser, nur in Vorlagen einzutauchen, die diese Variable benötigen. In diesem Fall ist es nicht sinnvoll, die Variable an alle Vorlagen zu übergeben. Wenn Sie die Variable jedoch in eine allgemeine Vorlage wie die base.html-Vorlage senden, spielt dies keine Rolle, da die base.html-Vorlage bei jeder Anforderung gerendert wird, sodass Sie beide Methoden verwenden können.
Wenn Sie sich für die Option "Vorlagen-Tags" entscheiden, verwenden Sie den folgenden Code, um einen Standard zu übergeben können, nur für den Fall, dass die betreffende Variable undefiniert war.
Beispiel: get_from_settings my_variable als my_context_value
Beispiel: get_from_settings my_variable my_default als 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)
SITE_EXTRA_CONTEXT_DICT
in der Finalware verwenden , um dies für Sie zu tun.