Designfilosofier¶
Detta dokument förklarar några av de grundläggande filosofier som Djangos utvecklare har använt för att skapa ramverket. Dess mål är att förklara det förflutna och vägleda framtiden.
Övergripande¶
Lösa kopplingar¶
Ett grundläggande mål för Djangos stack är lös koppling och tät sammanhållning. De olika lagren i ramverket ska inte ”veta” om varandra om det inte är absolut nödvändigt.
Mallsystemet vet t.ex. ingenting om webbförfrågningar, databaslagret vet ingenting om datavisning och visningssystemet bryr sig inte om vilket mallsystem en programmerare använder.
Även om Django levereras med en komplett stack för enkelhetens skull, är delarna av stacken oberoende av varandra där det är möjligt.
Mindre kod¶
Django-appar ska använda så lite kod som möjligt; de ska sakna boilerplate. Django bör dra full nytta av Pythons dynamiska funktioner, till exempel introspektion.
Snabb utveckling¶
Poängen med ett webbramverk på 2000-talet är att göra de tråkiga aspekterna av webbutveckling snabba. Django bör möjliggöra otroligt snabb webbutveckling.
Upprepa inte dig själv (DRY)¶
Varje distinkt begrepp och/eller uppgift bör finnas på en och endast en plats. Redundans är dåligt. Normalisering är bra.
Ramverket bör, inom rimliga gränser, härleda så mycket som möjligt från så lite som möjligt.
Se även
Diskussionen om DRY på Portland Pattern Repository
Explicit är bättre än implicit¶
Detta är en grundläggande Python-princip som listas i PEP 20, och det innebär att Django inte ska göra för mycket ”magi” Magi bör inte hända om det inte finns en riktigt bra anledning till det. Magi är värt att använda endast om det skapar en enorm bekvämlighet som inte kan uppnås på andra sätt, och det implementeras inte på ett sätt som förvirrar utvecklare som försöker lära sig hur man använder funktionen.
Samstämmighet¶
Ramverket bör vara konsekvent på alla nivåer. Konsistens gäller allt från låg nivå (den Python-kodningsstil som används) till hög nivå (”upplevelsen” av att använda Django).
Modeller¶
Explicit är bättre än implicit¶
Fält bör inte anta vissa beteenden enbart baserat på fältets namn. Detta kräver för mycket kunskap om systemet och är felbenäget. Istället bör beteenden baseras på nyckelordsargument och, i vissa fall, på fältets typ.
Inkludera all relevant domänlogik¶
Modeller ska kapsla in alla aspekter av ett ”objekt”, enligt Martin Fowlers designmönster Active Record.
Det är därför som både de data som representeras av en modell och information om den (dess mänskligt läsbara namn, alternativ som standardordning etc.) definieras i modellklassen; all information som behövs för att förstå en viss modell bör lagras i modellen.
Databas-API¶
De viktigaste målen för databas-API:et är:
SQL-effektivitet¶
Den ska exekvera SQL-satser så få gånger som möjligt och den ska optimera satserna internt.
Det är därför som utvecklare måste anropa save()
explicit, i stället för att ramverket sparar saker bakom kulisserna i tysthet.
Det är också därför som metoden select_related() `` ``QuerySet
finns. Det är en valfri prestandaförstärkare för det vanliga fallet att välja ”varje relaterat objekt”
Kortfattad, kraftfull syntax¶
Databas-API:et bör tillåta omfattande, uttrycksfulla uttalanden med så lite syntax som möjligt. Det ska inte vara beroende av import av andra moduler eller hjälpobjekt.
Sammanfogningar bör utföras automatiskt, bakom kulisserna, när det behövs.
Varje objekt bör kunna komma åt alla relaterade objekt i hela systemet. Denna åtkomst bör fungera åt båda hållen.
Möjlighet att enkelt gå över till raw SQL när det behövs¶
Databas-API:et bör inse att det är en genväg, men inte nödvändigtvis en universallösning. Ramverket bör göra det enkelt att skriva anpassad SQL - hela uttalanden eller bara anpassade WHERE
-klausuler som anpassade parametrar till API-anrop.
URL-design¶
Lösa kopplingar¶
URL:er i en Django-app ska inte kopplas till den underliggande Python-koden. Att binda webbadresser till Python-funktionsnamn är en dålig och ful sak.
I linje med detta bör Djangos URL-system tillåta att URL:er för samma app kan vara olika i olika sammanhang. Till exempel kan en webbplats lägga berättelser på /stories/
, medan en annan kan använda /news/
.
Oändlig flexibilitet¶
URL:er bör vara så flexibla som möjligt. Alla tänkbara utformningar av webbadresser bör tillåtas.
Uppmuntra bästa praxis¶
Ramverket bör göra det lika enkelt (eller till och med enklare) för en utvecklare att skapa snygga webbadresser som fula.
Filtillägg i webbsidors URL:er bör undvikas.
Vignettliknande kommatecken i webbadresser förtjänar stränga straff.
Definitiva webbadresser¶
Tekniskt sett är foo.com/bar
och foo.com/bar/
två olika webbadresser, och sökmotorrobotar (och vissa verktyg för analys av webbtrafik) skulle behandla dem som separata sidor. Django bör anstränga sig för att ”normalisera” webbadresser så att sökmotorrobotar inte blir förvirrade.
Detta är resonemanget bakom inställningen APPEND_SLASH
.
Mallsystem¶
Skilj logik från presentation¶
Vi ser ett mallsystem som ett verktyg som kontrollerar presentation och presentationsrelaterad logik - och det är allt. Mallsystemet bör inte stödja funktionalitet som går utöver detta grundläggande mål.
Motverka redundans¶
De flesta dynamiska webbplatser använder någon form av gemensam design för hela webbplatsen - en gemensam sidhuvud, sidfot, navigeringsfält osv. Djangos mallsystem bör göra det enkelt att lagra dessa element på ett enda ställe, vilket eliminerar dubbel kod.
Detta är filosofin bakom :ref:``template inheritance <template-inheritance>`.
Kopplas bort från HTML¶
Mallsystemet bör inte vara utformat så att det bara genererar HTML. Det bör vara lika bra på att generera andra textbaserade format, eller bara vanlig text.
XML bör inte användas för mallspråk¶
Att använda en XML-motor för att analysera mallar innebär en helt ny värld av mänskliga fel vid redigering av mallar - och en oacceptabel nivå av overhead vid mallbearbetning.
Utgå från designerns kompetens¶
Mallsystemet bör inte utformas så att mallar nödvändigtvis visas snyggt i WYSIWYG-editorer som Dreamweaver. Det är en alltför allvarlig begränsning och skulle inte tillåta syntaxen att vara så fin som den är. Django förväntar sig att mallförfattare är bekväma med att redigera HTML direkt.
Behandla blanksteg på ett självklart sätt¶
Mallsystemet bör inte göra magiska saker med blanksteg. Om en mall innehåller blanksteg bör systemet behandla blanksteget som text - bara visa det. Alla blanksteg som inte finns i en malltagg ska visas.
Uppfinn inte ett programmeringsspråk¶
Målet är inte att uppfinna ett programmeringsspråk. Målet är att erbjuda precis tillräckligt med programmeringsliknande funktionalitet, såsom förgrening och looping, som är nödvändig för att fatta presentationsrelaterade beslut. Django Template Language (DTL) syftar till att undvika avancerad logik.
Trygghet och säkerhet¶
Mallsystemet bör i utgångsläget förbjuda införandet av skadlig kod - till exempel kommandon som raderar databasposter.
Detta är ytterligare ett skäl till att mallsystemet inte tillåter godtycklig Python-kod.
Utökad tillgänglighet¶
Mallsystemet bör vara medvetet om att avancerade mallförfattare kan vilja utöka dess teknik.
Detta är filosofin bakom anpassade malltaggar och filter.
Vyer¶
Enkelhet¶
Att skriva en vy borde vara lika enkelt som att skriva en Python-funktion. Utvecklare ska inte behöva instansiera en klass när det räcker med en funktion.
Använda förfrågningsobjekt¶
Vyer bör ha tillgång till ett request-objekt - ett objekt som lagrar metadata om den aktuella förfrågan. Objektet bör skickas direkt till en vyfunktion, i stället för att vyfunktionen måste komma åt förfrågningsdata från en global variabel. Detta gör det lätt, rent och enkelt att testa vyer genom att skicka in ”falska” request-objekt.
Lösa kopplingar¶
En vy bör inte bry sig om vilket mallsystem utvecklaren använder - eller ens om ett mallsystem används överhuvudtaget.
Skillnad mellan GET och POST¶
GET och POST är olika; utvecklare bör uttryckligen använda det ena eller det andra. Ramverket bör göra det lätt att skilja mellan GET- och POST-data.
Cache-ramverk¶
De centrala målen för Djangos cache-ramverk är:
Mindre kod¶
En cache bör vara så snabb som möjligt. Därför bör all ramkod som omger cache-backend hållas till ett absolut minimum, särskilt för get()
-operationer.
Samstämmighet¶
Cache-API:et bör tillhandahålla ett konsekvent gränssnitt för de olika cache-backends.
Utökad tillgänglighet¶
Cache-API:t bör vara utbyggbart på applikationsnivå baserat på utvecklarens behov (se t.ex. Transformation av cache-nyckel).