Djangos mallspråk: för Python-programmerare¶
Detta dokument förklarar Djangos mallsystem ur ett tekniskt perspektiv - hur det fungerar och hur man utökar det. Om du letar efter en referens om språkets syntax, se Djangos mallspråk.
Det förutsätter en förståelse för mallar, kontexter, variabler, taggar och rendering. Börja med introduktion till Djangos mallspråk om du inte är bekant med dessa begrepp.
Översikt¶
Att använda mallsystemet i Python är en process i tre steg:
Du konfigurerar en :klass:`Engine`.
Du sammanställer mallkod till en
Template
.Du renderar mallen med en
Context
.
Djangoprojekt förlitar sig i allmänhet på :ref: hög nivå, backend agnostiska API:er <template-engines> för vart och ett av dessa steg istället för mallsystemets API:er på lägre nivå:
För varje
DjangoTemplates
backend iTEMPLATES
inställningen, instansierar Django enEngine
.DjangoTemplates
omsluterEngine
och anpassar den till det gemensamma mall backend API.Modulen
django.template.loader
tillhandahåller funktioner somget_template()
för att ladda mallar. De returnerar endjango.template.backends.django.Template
som omsluter den faktiskadjango.template.Template
.Den
Template
som erhölls i föregående steg har enrender()
-metod som samlar en kontext och eventuellt en begäran i enContext
och delegerar renderingen till den underliggandeTemplate
.
Konfigurera en motor¶
Om du använder DjangoTemplates
backend, är detta förmodligen inte den dokumentation du letar efter. En instans av klassen Engine
som beskrivs nedan är tillgänglig med hjälp av attributet engine
för den backend och alla attributstandarder som nämns nedan åsidosätts av det som skickas av DjangoTemplates
.
- class Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None, autoescape=True)[source]¶
Vid instansiering av en
Engine
måste alla argument skickas som nyckelordsargument:dirs
är en lista över kataloger där motorn ska leta efter mallkällfiler. Den används för att konfigurerafilesystem.Loader
.Standardvärdet är en tom lista.
app_dirs
påverkar endast standardvärdet förloaders
. Se nedan.Standardvärdet är
False
.autoescape
kontrollerar om HTML autoescaping är aktiverat.Standardvärdet är
True
.Varning
Sätt den bara till
False
om du renderar icke-HTML-mallar!context_processors
är en lista med prickade Python-sökvägar till anropsbara filer som används för att fylla i kontexten när en mall renderas med en begäran. Dessa callables tar ett request-objekt som sitt argument och returnerar endict
av objekt som ska sammanfogas i kontexten.Standardvärdet är en tom lista.
Se
RequestContext
för mer information.debug
är en boolean som aktiverar/avaktiverar mallens felsökningsläge. Om det ärTrue
kommer mallmotorn att lagra ytterligare felsökningsinformation som kan användas för att visa en detaljerad rapport för alla undantag som uppstår under mallrenderingen.Standardvärdet är
False
.loaders
är en lista över mallinläsningsklasser, specificerade som strängar. VarjeLoader
-klass vet hur man importerar mallar från en viss källa. Alternativt kan en tupel användas i stället för en sträng. Det första objektet i tupeln bör vara klassnamnet förLoader
, efterföljande objekt skickas tillLoader
under initialiseringen.Den innehåller som standard en lista:
'django.template.loaders.filesystem.Loader'`
'django.template.loaders.app_directories.Loader'
om och endast omapp_dirs
ärTrue
.
Dessa laddare är sedan inkapslade i
django.template.loaders.cached.Loader
.Se Typer av lastare för mer information.
string_if_invalid
är utdata i form av en sträng som mallsystemet ska använda för ogiltiga (t.ex. felstavade) variabler.Standardvärdet är den tomma strängen.
Se Hur ogiltiga variabler hanteras för mer information.
file_charset
är det teckensnitt som används för att läsa mallfiler på disken.Standardvärdet är
'utf-8'
.'bibliotek'
: En ordbok med etiketter och prickade Python-sökvägar för malltaggmoduler som ska registreras med mallmotorn. Detta används för att lägga till nya bibliotek eller tillhandahålla alternativa etiketter för befintliga bibliotek. Till exempel:Engine( libraries={ "myapp_tags": "path.to.myapp.tags", "admin.urls": "django.contrib.admin.templatetags.admin_urls", }, )
Bibliotek kan laddas genom att skicka motsvarande ordboksnyckel till taggen
{% load %}
.'builtins'
: En lista med prickade Python-sökvägar för malltaggmoduler som ska läggas till i built-ins. Till exempel:Engine( builtins=["myapp.builtins"], )
Taggar och filter från inbyggda bibliotek kan användas utan att först anropa taggen
{% load %}
.
- static Engine.get_default()[source]¶
Returnerar den underliggande
Engine
från den första konfigureradeDjangoTemplates
-motorn. UtlöserImproperlyConfigured
om inga motorer är konfigurerade.Det krävs för att bevara API:er som förlitar sig på en globalt tillgänglig, implicit konfigurerad motor. All annan användning är starkt avrådd.
- Engine.from_string(template_code)[source]¶
Kompilerar den angivna mallkoden och returnerar ett
Template
-objekt.
- Engine.get_template(template_name)[source]¶
Läser in en mall med det angivna namnet, kompilerar den och returnerar ett
Template
-objekt.
- Engine.select_template(template_name_list)[source]¶
Som
get_template()
, förutom att den tar en lista med namn och returnerar den första mallen som hittades.
Ladda en mall¶
Det rekommenderade sättet att skapa en Template
är att anropa fabriksmetoderna i Engine
: get_template()
, select_template()
och from_string()
.
I ett Django-projekt där inställningen TEMPLATES
definierar en DjangoTemplates
-motor, är det möjligt att instansiera en Template
direkt. Om mer än en DjangoTemplates
-motor är definierad, kommer den första att användas.
- class Template[source]¶
Denna klass lever på
django.template.Template
. Konstruktören tar ett argument - den råa mallkoden:from django.template import Template template = Template("My name is {{ my_name }}.")
Bakom kulisserna
Systemet analyserar bara din råa mallkod en gång - när du skapar objektet Template
. Från och med då lagras den internt som en trädstruktur för prestanda.
Även själva parsningen är ganska snabb. Det mesta av parsningen sker via ett enda anrop till ett enda, kort, reguljärt uttryck.
Rendering av en kontext¶
När du har ett kompilerat Template
-objekt kan du rendera en kontext med det. Du kan återanvända samma mall för att rendera den flera gånger med olika kontexter.
- class Context(dict_=None, autoescape=True, use_l10n=None, use_tz=None)[source]¶
Konstruktören för
django.template.Context
tar ett valfritt argument - en ordbok som mappar variabelnamn till variabelvärden.Tre valfria nyckelordsargument kan också anges:
autoescape
kontrollerar om HTML autoescaping är aktiverat.Standardvärdet är
True
.Varning
Sätt den bara till
False
om du renderar icke-HTML-mallar!use_l10n
åsidosätter om värden ska lokaliseras som standard. Om inställningen ärTrue
kommer siffror och datum att formateras baserat på lokal.Standardvärdet är
None
.Se Styrning av lokalisering i mallar för detaljer.
use_tz
åsidosätter om datum konverteras till lokal tid när de återges i en mall. Om inställningen ärTrue
kommer alla datum att återges med den lokala tidszonen. Detta har företräde framförUSE_TZ
.Standardvärdet är
None
.Se tidszoner-i-mallar för mer information.
För exempel på användning, se Leka med Context-objekt nedan.
- Template.render(context)[source]¶
Anropa
Template
-objektetsrender()
-metod med enContext
för att ”fylla” mallen:>>> from django.template import Context, Template >>> template = Template("My name is {{ my_name }}.") >>> context = Context({"my_name": "Adrian"}) >>> template.render(context) "My name is Adrian." >>> context = Context({"my_name": "Dolores"}) >>> template.render(context) "My name is Dolores."
Variabler och uppslagsord¶
Variabelnamn får bestå av valfri bokstav (A-Z), valfri siffra (0-9), en understrykning (men de får inte börja med en understrykning) eller en punkt.
Prickar har en speciell betydelse i mallrendering. En punkt i ett variabelnamn betyder en uppslagning. När mallsystemet stöter på en punkt i ett variabelnamn försöker det med följande uppslagningar, i den här ordningen:
Uppslagning i ordbok. Exempel:
foo["bar"]
Uppslagning av attribut. Exempel:
foo.bar
Uppslagning i listindex. Exempel:
foo[bar]
Observera att ”bar” i ett malluttryck som {{ foo.bar }}
kommer att tolkas som en bokstavlig sträng och inte som värdet på variabeln ”bar”, om en sådan finns i mallkontexten.
Mallsystemet använder den första uppslagstypen som fungerar. Det är kortslutningslogik. Här är några exempel:
>>> from django.template import Context, Template
>>> t = Template("My name is {{ person.first_name }}.")
>>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
>>> t.render(Context(d))
"My name is Joe."
>>> class PersonClass:
... pass
...
>>> p = PersonClass()
>>> p.first_name = "Ron"
>>> p.last_name = "Nasty"
>>> t.render(Context({"person": p}))
"My name is Ron."
>>> t = Template("The first stooge in the list is {{ stooges.0 }}.")
>>> c = Context({"stooges": ["Larry", "Curly", "Moe"]})
>>> t.render(c)
"The first stooge in the list is Larry."
Om någon del av variabeln är anropsbar kommer mallsystemet att försöka anropa den. Exempel på detta:
>>> class PersonClass2:
... def name(self):
... return "Samantha"
...
>>> t = Template("My name is {{ person.name }}.")
>>> t.render(Context({"person": PersonClass2}))
"My name is Samantha."
Kallbara variabler är något mer komplexa än variabler som bara kräver direkta uppslagningar. Här är några saker att tänka på:
Om variabeln ger upphov till ett undantag när den anropas kommer undantaget att spridas, såvida inte undantaget har ett attribut
silent_variable_failure
vars värde ärTrue
. Om undantaget har ett attributsilent_variable_failure
vars värde ärTrue
, kommer variabeln att återges som värdet av motorns konfigurationsalternativstring_if_invalid
(en tom sträng som standard). Exempel på detta:>>> t = Template("My name is {{ person.first_name }}.") >>> class PersonClass3: ... def first_name(self): ... raise AssertionError("foo") ... >>> p = PersonClass3() >>> t.render(Context({"person": p})) Traceback (most recent call last): ... AssertionError: foo >>> class SilentAssertionError(Exception): ... silent_variable_failure = True ... >>> class PersonClass4: ... def first_name(self): ... raise SilentAssertionError ... >>> p = PersonClass4() >>> t.render(Context({"person": p})) "My name is ."
Observera att
django.core.exceptions.ObjectDoesNotExist
, som är basklassen för alla Django databas APIDoesNotExist
undantag, harsilent_variable_failure = True
. Så om du använder Django-mallar med Django-modellobjekt, kommer allaDoesNotExist
-undantag att misslyckas tyst.En variabel kan bara anropas om den inte har några nödvändiga argument. I annat fall returnerar systemet värdet på motorns alternativ
string_if_invalid
.
Det kan finnas bieffekter när man anropar vissa variabler, och det skulle vara antingen dumt eller ett säkerhetshål att låta mallsystemet komma åt dem.
Ett bra exempel är
delete()
-metoden på varje Django-modellobjekt. Mallsystemet bör inte tillåtas att göra något liknande:I will now delete this valuable data. {{ data.delete }}
För att förhindra detta ska du ange attributet
alters_data
för den anropbara variabeln. Mallsystemet kommer inte att anropa en variabel om den haralters_data=True
inställd, och kommer istället att ersätta variabeln medstring_if_invalid
, ovillkorligen. De dynamiskt genereradedelete()
ochsave()
metoderna på Django modellobjekt fåralters_data=True
automatiskt. Exempel:def sensitive_function(self): self.database_record.delete() sensitive_function.alters_data = True
Ibland kanske du vill stänga av den här funktionen av andra skäl och tala om för mallsystemet att en variabel ska lämnas oanropad oavsett vad som händer. För att göra det, ställ in ett
do_not_call_in_templates
-attribut på den anropbara variabeln med värdetTrue
. Mallsystemet kommer då att agera som om din variabel inte är anropsbar (så att du till exempel kan komma åt attribut för den anropsbara variabeln).
Hur ogiltiga variabler hanteras¶
Om en variabel inte finns infogar mallsystemet i allmänhet värdet för motorns konfigurationsalternativ string_if_invalid
, som är inställt på ''
(den tomma strängen) som standard.
Filter som tillämpas på en ogiltig variabel tillämpas endast om string_if_invalid
är inställd på ''
(den tomma strängen). Om string_if_invalid
är satt till något annat värde ignoreras variabelfiltren.
Detta beteende är något annorlunda för malltaggarna if
, for
och regroup
. Om en ogiltig variabel anges i en av dessa malltaggar tolkas variabeln som None
. Filter tillämpas alltid på ogiltiga variabler inom dessa malltaggar.
Om string_if_invalid
innehåller en '%s'
ersätts formatmarkören med namnet på den ogiltiga variabeln.
Endast för felsökningsändamål!
Även om string_if_invalid
kan vara ett användbart felsökningsverktyg är det en dålig idé att aktivera det som en ”utvecklingsstandard”.
Många mallar, inklusive några av Djangos, förlitar sig på mallsystemets tystnad när en icke-existerande variabel påträffas. Om du tilldelar ett annat värde än ''
till string_if_invalid
, kommer du att uppleva renderingsproblem med dessa mallar och webbplatser.
I allmänhet bör string_if_invalid
endast aktiveras för att felsöka ett specifikt mallproblem, och sedan tas bort när felsökningen är klar.
Inbyggda variabler¶
Varje kontext innehåller True
, False
och None
. Som du kan förvänta dig löses dessa variabler upp till motsvarande Python-objekt.
Begränsningar med stränglitteraler¶
Djangos mallspråk har inget sätt att undkomma de tecken som används för dess egen syntax. Till exempel: krävs taggen templatetag
om du behöver skriva ut teckensekvenser som {%
och %}
.
Ett liknande problem finns om du vill inkludera dessa sekvenser i mallfilter eller taggargument. Till exempel:, när man analyserar en block-tagg, letar Djangos mallanalysator efter den första förekomsten av %}
efter en {%
. Detta förhindrar användningen av "%}"
som en bokstavlig sträng. Till exempel: kommer ett TemplateSyntaxError
att uppstå för följande uttryck:
{% include "template.html" tvar="Some string literal with %} in it." %}
{% with tvar="Some string literal with %} in it." %}{% endwith %}
Samma problem kan uppstå om man använder en reserverad sekvens i filterargument:
{{ some.variable|default:"}}" }}
Om du behöver använda strängar med dessa sekvenser kan du lagra dem i mallvariabler eller använda en anpassad malltagg eller ett filter för att kringgå begränsningen.
Leka med Context
-objekt¶
För det mesta instansierar du Context
-objekt genom att skicka in en fullständigt fylld ordbok till Context()
. Men du kan också lägga till och ta bort objekt från ett Context
-objekt när det har instantierats, med hjälp av standardordbokssyntax:
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c["foo"]
'bar'
>>> del c["foo"]
>>> c["foo"]
Traceback (most recent call last):
...
KeyError: 'foo'
>>> c["newvariable"] = "hello"
>>> c["newvariable"]
'hello'
- Context.get(key, otherwise=None)¶
Returnerar värdet för
key
omkey
finns i kontexten, annars returnerasannat
.
- Context.setdefault(key, default=None)¶
Om
key
finns i kontexten returneras dess värde. Annars infogarkey
med värdetdefault
och returnerardefault
.
- Context.pop()¶
- Context.push()¶
Ett Context
-objekt är en stack. Det vill säga, du kan push()
och pop()
det. Om du pop()
för mycket, kommer det att ge upphov till django.template.ContextPopException
:
>>> c = Context()
>>> c["foo"] = "first level"
>>> c.push()
{}
>>> c["foo"] = "second level"
>>> c["foo"]
'second level'
>>> c.pop()
{'foo': 'second level'}
>>> c["foo"]
'first level'
>>> c["foo"] = "overwritten"
>>> c["foo"]
'overwritten'
>>> c.pop()
Traceback (most recent call last):
...
ContextPopException
Du kan också använda push()
som en kontexthanterare för att säkerställa att en matchande pop()
anropas.
>>> c = Context()
>>> c["foo"] = "first level"
>>> with c.push():
... c["foo"] = "second level"
... c["foo"]
...
'second level'
>>> c["foo"]
'first level'
Alla argument som skickas till push()
kommer att skickas till dict
-konstruktören som används för att bygga den nya kontextnivån.
>>> c = Context()
>>> c["foo"] = "first level"
>>> with c.push(foo="second level"):
... c["foo"]
...
'second level'
>>> c["foo"]
'first level'
Förutom push()
och pop()
definierar objektet Context
också en metod för update()
. Denna fungerar som push()
men tar en ordbok som argument och skjuter den ordboken på stacken istället för en tom.
>>> c = Context()
>>> c["foo"] = "first level"
>>> c.update({"foo": "updated"})
{'foo': 'updated'}
>>> c["foo"]
'updated'
>>> c.pop()
{'foo': 'updated'}
>>> c["foo"]
'first level'
Precis som push()
kan du använda update()
som en kontexthanterare för att säkerställa att en matchande pop()
anropas.
>>> c = Context()
>>> c["foo"] = "first level"
>>> with c.update({"foo": "second level"}):
... c["foo"]
...
'second level'
>>> c["foo"]
'first level'
Att använda en Context
som en stack är praktiskt i :ref:``några anpassade malltaggar <howto-writing-custom-template-tags>`.
- Context.flatten()¶
Med hjälp av metoden flatten()
kan du få hela Context
-stacken som en ordbok inklusive inbyggda variabler.
>>> c = Context()
>>> c["foo"] = "first level"
>>> c.update({"bar": "second level"})
{'bar': 'second level'}
>>> c.flatten()
{'True': True, 'None': None, 'foo': 'first level', 'False': False, 'bar': 'second level'}
En flatten()
-metod används också internt för att göra Context
-objekt jämförbara.
>>> c1 = Context()
>>> c1["foo"] = "first level"
>>> c1["bar"] = "second level"
>>> c2 = Context()
>>> c2.update({"bar": "second level", "foo": "first level"})
{'foo': 'first level', 'bar': 'second level'}
>>> c1 == c2
True
Resultatet från flatten()
kan vara användbart i enhetstester för att jämföra Context
mot dict
:
class ContextTest(unittest.TestCase):
def test_against_dictionary(self):
c1 = Context()
c1["update"] = "value"
self.assertEqual(
c1.flatten(),
{
"True": True,
"None": None,
"False": False,
"update": "value",
},
)
Använda RequestContext
¶
- class RequestContext(request, dict_=None, processors=None, use_l10n=None, use_tz=None, autoescape=True)[source]¶
Django kommer med en speciell Context
-klass, django.template.RequestContext
, som fungerar något annorlunda än den normala django.template.Context
. Den första skillnaden är att den tar en HttpRequest
som sitt första argument. Till exempel:
c = RequestContext(
request,
{
"foo": "bar",
},
)
Den andra skillnaden är att den automatiskt fyller i kontexten med några variabler, enligt motorns konfigurationsalternativ context_processors
.
Alternativet context_processors
är en lista över anropbara objekt - kallade kontextprocessorer - som tar ett request-objekt som argument och returnerar en ordbok med objekt som ska sammanfogas i kontexten. I den standardgenererade inställningsfilen innehåller standardmallmotorn följande kontextprocessorer:
[
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
Utöver dessa aktiverar RequestContext
alltid 'django.template.context_processors.csrf'
. Detta är en säkerhetsrelaterad kontextprocessor som krävs av admin och andra contrib-appar, och i händelse av oavsiktlig felkonfiguration är den avsiktligt hårdkodad och kan inte stängas av i alternativet context_processors
.
Varje processor tillämpas i tur och ordning. Det innebär att om en processor lägger till en variabel i sammanhanget och en andra processor lägger till en variabel med samma namn, kommer den andra processorn att åsidosätta den första. Standardprocessorerna förklaras nedan.
När kontextprocessorer används
Kontextprocessorer tillämpas ovanpå kontextdata. Detta innebär att en kontextprocessor kan skriva över variabler som du har angett i din Context
eller RequestContext
, så se till att undvika variabelnamn som överlappar med dem som anges av dina kontextprocessorer.
Om du vill att kontextdata ska prioriteras framför kontextprocessorer använder du följande mönster:
from django.template import RequestContext
request_context = RequestContext(request)
request_context.push({"my_name": "Adrian"})
Django gör detta för att tillåta att kontextdata åsidosätter kontextprocessorer i API:er som render()
och TemplateResponse
.
Du kan också ge RequestContext
en lista över ytterligare processorer genom att använda det valfria, tredje positionsargumentet, processors
. I detta exempel får RequestContext
-instansen en ip_address
-variabel:
from django.http import HttpResponse
from django.template import RequestContext, Template
def ip_address_processor(request):
return {"ip_address": request.META["REMOTE_ADDR"]}
def client_ip_view(request):
template = Template("{{ title }}: {{ ip_address }}")
context = RequestContext(
request,
{
"title": "Your IP Address",
},
[ip_address_processor],
)
return HttpResponse(template.render(context))
Inbyggda processorer för mallkontext¶
Här är vad var och en av de inbyggda processorerna gör:
django.contrib.auth.context_processors.auth
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla dessa variabler:
user
– Enauth.User
-instans som representerar den användare som för närvarande är inloggad (eller enAnonymousUser
-instans om klienten inte är inloggad).perms
– En instans avdjango.contrib.auth.context_processors.PermWrapper
, som representerar de behörigheter som den för närvarande inloggade användaren har.
django.template.context_processors.debug
¶
Om den här processorn är aktiverad kommer varje RequestContext
att innehålla dessa två variabler - men bara om inställningen DEBUG`
är satt till True
och begärans IP-adress (request.META['REMOTE_ADDR']
) finns i inställningen INTERNAL_IPS`
:
debug
–True
. Du kan använda detta i mallar för att testa om du är iDEBUG
-läge.sql_queries
– En lista med{'sql': ..., 'time': ...}
dictionaries, som representerar varje SQL-fråga som har skett hittills under begäran och hur lång tid det tog. Listan är ordnad efter databasalias och sedan efter fråga. Den genereras lättsamt vid åtkomst.
django.template.context_processors.i18n
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla dessa variabler:
LANGUAGES
– Värdet på inställningenLANGUAGES
.LANGUAGE_BIDI
–True
om det aktuella språket är ett höger-till-vänster-språk, t.ex. hebreiska, arabiska.False
om det är ett vänster till höger-språk, t.ex. engelska, franska, tyska.LANGUAGE_CODE
–request.LANGUAGE_CODE
, om det finns. Annars värdet av inställningenLANGUAGE_CODE
.
Se i18n malltaggar för malltaggar som genererar samma värden.
django.template.context_processors.media
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla en variabel MEDIA_URL
, som anger värdet på inställningen MEDIA_URL
.
django.template.context_processors.static
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla en variabel STATIC_URL
som anger värdet på inställningen STATIC_URL
.
django.template.context_processors.csrf
¶
Denna processor lägger till en token som behövs av malltaggen csrf_token
för skydd mot Cross Site Request Forgeries.
django.template.context_processors.request
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla en variabel request
, som är den aktuella HttpRequest
.
django.template.context_processors.tz
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla en variabel TIME_ZONE
, som anger namnet på den aktuella aktiva tidszonen.
django.contrib.messages.context_processors.messages
¶
Om denna processor är aktiverad kommer varje RequestContext
att innehålla dessa två variabler:
messages
– En lista över meddelanden (som strängar) som har ställts in via messages framework.DEFAULT_MESSAGE_LEVELS
– En mappning av meddelandenivåernas namn till :ref:``deras numeriska värde <message-level-constants>`.
Skriva dina egna kontextprocessorer¶
En kontextprocessor har ett enkelt gränssnitt: Det är en Python-funktion som tar ett argument, ett HttpRequest
-objekt, och returnerar en ordbok som läggs till i mallkontexten.
Till exempel:, för att lägga till inställningen DEFAULT_FROM_EMAIL
i varje kontext:
from django.conf import settings
def from_email(request):
return {
"DEFAULT_FROM_EMAIL": settings.DEFAULT_FROM_EMAIL,
}
Anpassade kontextprocessorer kan finnas var som helst i din kodbas. Allt Django bryr sig om är att dina anpassade kontextprocessorer pekas ut av alternativet 'context_processors'
i din inställning TEMPLATES
- eller argumentet context_processors
i Engine
om du använder det direkt.
Laddning av mallar¶
Generellt sett lagrar du mallar i filer på ditt filsystem snarare än att använda lågnivå Template
API själv. Spara mallar i en katalog som anges som en mallkatalog.
Django söker efter mallkataloger på ett antal ställen, beroende på dina inställningar för mallladdning (se ”Laddningstyper” nedan), men det mest grundläggande sättet att ange mallkataloger är genom att använda alternativet DIRS
.
Alternativet DIRS
¶
Berätta för Django vilka dina mallkataloger är genom att använda alternativet DIRS
i inställningen TEMPLATES
i din inställningsfil - eller argumentet dirs
i Engine
. Detta bör ställas in på en lista med strängar som innehåller fullständiga sökvägar till dina mallkataloger:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
"/home/html/templates/lawrence.com",
"/home/html/templates/default",
],
},
]
Dina mallar kan placeras var du vill, så länge katalogerna och mallarna kan läsas av webbservern. De kan ha vilket tillägg du vill, t.ex. .html
eller .txt
, eller inget tillägg alls.
Observera att dessa sökvägar ska använda snedstreck i Unix-stil, även under Windows.
Typer av lastare¶
Som standard använder Django en filsystembaserad mallladdare, men Django levereras med några andra mallladdare, som vet hur man laddar mallar från andra källor.
Några av dessa andra laddare är inaktiverade som standard, men du kan aktivera dem genom att lägga till ett 'loaders'
alternativ till din DjangoTemplates
backend i TEMPLATES
inställningen eller skicka ett loaders
argument till Engine
. loaders
bör vara en lista med strängar eller tupler, där var och en representerar en mallinläsningsklass. Här är de mallinläsare som följer med Django:
django.template.loaders.filesystem.Loader
- class filesystem.Loader¶
Läser in mallar från filsystemet enligt
DIRS
.Den här laddaren är aktiverad som standard. Den kommer dock inte att hitta några mallar förrän du ställer in
DIRS
till en icke-tom lista:TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [BASE_DIR / "templates"], } ]
Du kan också åsidosätta
'DIRS'
och ange specifika kataloger för en viss filsystemladdare:TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "OPTIONS": { "loaders": [ ( "django.template.loaders.filesystem.Loader", [BASE_DIR / "templates"], ), ], }, } ]
django.template.loaders.app_directories.Loader
- class app_directories.Loader¶
Laddar mallar från Django-appar på filsystemet. För varje app i
INSTALLED_APPS
letar laddaren efter en underkatalog med namnettemplates
. Om katalogen finns letar Django efter mallar i den.Detta innebär att du kan lagra mallar med dina enskilda appar. Detta hjälper också till att distribuera Django-appar med standardmallar.
Till exempel:, för denna inställning:
INSTALLED_APPS = ["myproject.polls", "myproject.music"]
…då kommer
get_template('foo.html')
att leta efterfoo.html
i dessa kataloger, i denna ordning:/path/to/myproject/polls/templates/
/path/to/myproject/music/templates/
… och kommer att använda den som den hittar först.
Ordningen på
INSTALLED_APPS
är viktig! Om du till exempel vill anpassa Django-adminen kan du välja att åsidosätta standardmallenadmin/base_site.html
fråndjango.contrib.admin
med din egenadmin/base_site.html
imyproject.polls
. Du måste då se till att dinmyproject.polls
kommer föredjango.contrib.admin
iINSTALLED_APPS
, annars kommerdjango.contrib.admin
att laddas först och din kommer att ignoreras.Observera att laddaren utför en optimering när den körs första gången: den cachar en lista över vilka
INSTALLED_APPS
-paket som har entemplates
-underkatalog.Du kan aktivera den här laddaren genom att ställa in
APP_DIRS
tillTrue
:TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "APP_DIRS": True, } ]
django.template.loaders.cached.Loader
- class cached.Loader¶
Djangos mallsystem är visserligen ganska snabbt, men om det behöver läsa och kompilera dina mallar varje gång de renderas kan omkostnaderna för detta bli höga.
Du konfigurerar den cachade mallladdaren med en lista över andra laddare som den ska omsluta. De omslutna laddarna används för att lokalisera okända mallar när de först påträffas. Den cachade laddaren lagrar sedan den kompilerade
Template
i minnet. Den cachadeTemplate
-instansen returneras för efterföljande förfrågningar om att ladda samma mall.Den här laddaren aktiveras automatiskt om
OPTIONS['loaders']
inte har angetts.Du kan manuellt ange cachning av mallar med vissa anpassade mallladdare med inställningar som denna:
TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [BASE_DIR / "templates"], "OPTIONS": { "loaders": [ ( "django.template.loaders.cached.Loader", [ "django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader", "path.to.custom.Loader", ], ), ], }, } ]
Observera
Alla de inbyggda Django-malltaggarna är säkra att använda med den cachade laddaren, men om du använder anpassade malltaggar som kommer från tredjepartspaket, eller som du skrev själv, bör du se till att
Node
-implementeringen för varje tagg är trådsäker. För mer information, se överväganden om trådsäkerhet för malltaggar.
django.template.loaders.locmem.Loader
- class locmem.Loader¶
Läser in mallar från en Python-ordbok. Detta är användbart för testning.
Denna laddare tar en ordlista med mallar som sitt första argument:
TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "OPTIONS": { "loaders": [ ( "django.template.loaders.locmem.Loader", { "index.html": "content here", }, ), ], }, } ]
Denna laddare är avaktiverad som standard.
Django använder mallladdarna i ordning enligt alternativet 'loaders
. Den använder varje laddare tills en laddare hittar en matchning.
Anpassade lastare¶
Det är möjligt att ladda mallar från ytterligare källor med hjälp av anpassade mallladdare. Anpassade Loader
-klasser bör ärva från django.template.loaders.base.Loader
och definiera metoderna get_contents()
och get_template_sources()
.
Metoder för lastare¶
- class Loader[source]¶
Läser in mallar från en viss källa, t.ex. filsystemet eller en databas.
- get_template_sources(template_name)[source]¶
En metod som tar ett
template_name
och gerOrigin
-instanser för varje möjlig källa.Filsystemladdaren kan till exempel ta emot
'index.html
som etttemplate_name
-argument. Denna metod skulle ge ursprung för den fullständiga sökvägen tillindex.html
som den visas i varje mallkatalog som laddaren tittar på.Metoden behöver inte verifiera att mallen finns på en given sökväg, men den bör säkerställa att sökvägen är giltig. Filsystemladdaren ser t.ex. till att sökvägen ligger under en giltig mallkatalog.
- get_contents(origin)¶
Returnerar innehållet för en mall som ges en
Origin
-instans.Det är här en filsystemladdare skulle läsa innehåll från filsystemet, eller en databasladdare skulle läsa från databasen. Om en matchande mall inte finns, bör detta ge upphov till ett
TemplateDoesNotExist
-fel.
- get_template(template_name, skip=None)[source]¶
Returnerar ett
Template
-objekt för ett givettemplate_name
genom att loopa genom resultaten frånget_template_sources()
och anropaget_contents()
. Detta returnerar den första matchande mallen. Om ingen mall hittas,TemplateDoesNotExist
tas upp.Det valfria argumentet
skip
är en lista över ursprung som ska ignoreras när mallar utökas. Detta gör det möjligt för mallar att utöka andra mallar med samma namn. Det används också för att undvika rekursionsfel.I allmänhet räcker det med att definiera
get_template_sources()
ochget_contents()
för anpassade mallladdare.`get_template()
behöver vanligtvis inte åsidosättas.
Bygg din egen
För exempel, läs källkod för Djangos inbyggda laddare.
Mall för ursprung¶
Mallar har ett origin
som innehåller attribut beroende på vilken källa de laddas från.
- class Origin(name, template_name=None, loader=None)[source]¶
- name¶
Sökvägen till mallen som returneras av mallladdaren. För laddare som läser från filsystemet är detta den fullständiga sökvägen till mallen.
Om mallen instansieras direkt i stället för via en mallladdare är detta ett strängvärde av
<unknown_source>
.
- template_name¶
Den relativa sökvägen till mallen som skickas till mallladdaren.
Om mallen instansieras direkt i stället för via en mallladdare är detta
None
.
- loader¶
Den instans av mallladdaren som skapade denna
Origin
.Om mallen instansieras direkt i stället för via en mallladdare är detta
None
.django.template.loaders.cached.Loader
kräver att alla dess omslutna laddare ställer in detta attribut, vanligtvis genom att instansieraOrigin
medloader=self
.