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
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
DjangoTemplatesbackend iTEMPLATESinställningen, instansierar Django enEngine.DjangoTemplatesomsluterEngineoch anpassar den till det gemensamma mall backend API.Modulen
django.template.loadertillhandahåller funktioner somget_template()för att ladda mallar. De returnerar endjango.template.backends.django.Templatesom omsluter den faktiskadjango.template.Template.Den
Templatesom erhölls i föregående steg har enrender()-metod som samlar en kontext och eventuellt en begäran i enContextoch 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
Enginemå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_dirspåverkar endast standardvärdet förloaders. Se nedan.Standardvärdet är
False.autoescapekontrollerar om HTML autoescaping är aktiverat.Standardvärdet är
True.Varning
Sätt den bara till
Falseom 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 endictav objekt som ska sammanfogas i kontexten.Standardvärdet är en tom lista.
Se
RequestContextför mer information.debugär en boolean som aktiverar/avaktiverar mallens felsökningsläge. Om det ärTruekommer 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 tillLoaderunder 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
Enginefrån den första konfigureradeDjangoTemplates-motorn. UtlöserImproperlyConfiguredom 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.Contexttar ett valfritt argument - en ordbok som mappar variabelnamn till variabelvärden.Tre valfria nyckelordsargument kan också anges:
autoescapekontrollerar om HTML autoescaping är aktiverat.Standardvärdet är
True.Varning
Sätt den bara till
Falseom du renderar icke-HTML-mallar!use_l10nåsidosätter om värden ska lokaliseras som standard. Om inställningen ärTruekommer 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 ärTruekommer 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 enContextfö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.barUppslagning 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_failurevars värde ärTrue. Om undantaget har ett attributsilent_variable_failurevars 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 APIDoesNotExistundantag, 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_dataför den anropbara variabeln. Mallsystemet kommer inte att anropa en variabel om den haralters_data=Trueinställd, och kommer istället att ersätta variabeln medstring_if_invalid, ovillkorligen. De dynamiskt genereradedelete()ochsave()metoderna på Django modellobjekt fåralters_data=Trueautomatiskt. 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
keyomkeyfinns i kontexten, annars returnerasannat.
- Context.setdefault(key, default=None)¶
Om
keyfinns i kontexten returneras dess värde. Annars infogarkeymed värdetdefaultoch 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 några anpassade malltaggar.
- 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–Trueom det aktuella språket är ett höger-till-vänster-språk, t.ex. hebreiska, arabiska.Falseom 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 deras numeriska värde.
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
DIRStill 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_APPSletar 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.htmli 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.htmlfråndjango.contrib.adminmed din egenadmin/base_site.htmlimyproject.polls. Du måste då se till att dinmyproject.pollskommer föredjango.contrib.adminiINSTALLED_APPS, annars kommerdjango.contrib.adminatt 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_DIRStillTrue: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
Templatei 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_nameoch gerOrigin-instanser för varje möjlig källa.Filsystemladdaren kan till exempel ta emot
'index.htmlsom etttemplate_name-argument. Denna metod skulle ge ursprung för den fullständiga sökvägen tillindex.htmlsom 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_namegenom att loopa genom resultaten frånget_template_sources()och anropaget_contents(). Detta returnerar den första matchande mallen. Om ingen mall hittas,TemplateDoesNotExisttas 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.Loaderkräver att alla dess omslutna laddare ställer in detta attribut, vanligtvis genom att instansieraOriginmedloader=self.