Django i en överblick¶
Eftersom Django utvecklades i en snabb nyhetsrumsmiljö, utformades det för att göra vanliga webbutvecklingsuppgifter snabba och enkla. Här är en informell översikt över hur man skriver en databasdriven webbapp med Django.
Målet med detta dokument är att ge dig tillräckligt med tekniska detaljer för att förstå hur Django fungerar, men det är inte avsett att vara en handledning eller referens - men vi har båda! När du är redo att starta ett projekt kan du börja med handledningen eller dyka rakt in i mer detaljerad dokumentation.
Utforma din modell¶
Även om du kan använda Django utan en databas, levereras den med en ”objekt-relationell mappare” där du beskriver din databaslayout i Python-kod.
Syntaxen datamodell erbjuder många olika sätt att representera dina modeller - hittills har den löst många års problem med databasscheman. Här är ett snabbt exempel:
nyheter/modeller.py
¶from django.db import models
class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __str__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
Installera den¶
Därefter kör du Djangos kommandoradsverktyg för att skapa databastabellerna automatiskt:
$ python manage.py makemigrations
$ python manage.py migrate
...\> py manage.py makemigrations
...\> py manage.py migrate
Kommandot makemigrations
tittar på alla dina tillgängliga modeller och skapar migreringar för de tabeller som inte redan finns. migrate
kör migreringarna och skapar tabeller i din databas, samt ger eventuellt mycket rikare schemakontroll.
Njut av det kostnadsfria API:et¶
Med det har du ett gratis och rikt Python API för att komma åt dina data. API:et skapas i farten, ingen kodgenerering är nödvändig:
# Import the models we created from our "news" app
>>> from news.models import Article, Reporter
# No reporters are in the system yet.
>>> Reporter.objects.all()
<QuerySet []>
# Create a new Reporter.
>>> r = Reporter(full_name="John Smith")
# Save the object into the database. You have to call save() explicitly.
>>> r.save()
# Now it has an ID.
>>> r.id
1
# Now the new reporter is in the database.
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>
# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'
# Django provides a rich database lookup API.
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith="John")
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains="mith")
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Reporter matching query does not exist.
# Create an article.
>>> from datetime import date
>>> a = Article(
... pub_date=date.today(), headline="Django is cool", content="Yeah.", reporter=r
... )
>>> a.save()
# Now the article is in the database.
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>
# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'
# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>
# The API follows relationships as far as you need, performing efficient
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with "John".
>>> Article.objects.filter(reporter__full_name__startswith="John")
<QuerySet [<Article: Django is cool>]>
# Change an object by altering its attributes and calling save().
>>> r.full_name = "Billy Goat"
>>> r.save()
# Delete an object with delete().
>>> r.delete()
Ett dynamiskt administratörsgränssnitt: det är inte bara en byggnadsställning - det är hela huset¶
När dina modeller är definierade kan Django automatiskt skapa ett professionellt, produktionsfärdigt administrativt gränssnitt - en webbplats som låter autentiserade användare lägga till, ändra och ta bort objekt. Det enda steget som krävs är att registrera din modell på administratörssidan:
nyheter/modeller.py
¶from django.db import models
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
nyheter/admin.py
¶from django.contrib import admin
from . import models
admin.site.register(models.Article)
Filosofin här är att din webbplats redigeras av en personal, en kund eller kanske bara du - och du vill inte behöva ta itu med att skapa backend-gränssnitt bara för att hantera innehåll.
Ett typiskt arbetsflöde för att skapa Django-appar är att skapa modeller och få igång administratörswebbplatserna så snabbt som möjligt, så att din personal (eller kunder) kan börja fylla i data. Utveckla sedan det sätt på vilket data presenteras för allmänheten.
Utforma dina webbadresser¶
Ett rent och elegant URL-schema är en viktig detalj i en högkvalitativ webbapplikation. Django uppmuntrar till vacker URL-design och lägger inte till något skräp i webbadresser, som .php
eller .asp
.
För att designa webbadresser för en app skapar du en Python-modul som kallas URLconf. Den är en innehållsförteckning för din app och innehåller en mappning mellan URL-mönster och Python callback-funktioner. URLconfs tjänar också till att frikoppla webbadresser från Python-kod.
Så här kan en URLconf se ut för exemplet Reporter
/Article
ovan:
nyheter/urls.py
¶from django.urls import path
from . import views
urlpatterns = [
path("articles/<int:year>/", views.year_archive),
path("articles/<int:year>/<int:month>/", views.month_archive),
path("articles/<int:year>/<int:month>/<int:pk>/", views.article_detail),
]
Koden ovan mappar URL-sökvägar till Python callback-funktioner (”views”). Söksträngarna använder parametertaggar för att ”fånga” värden från webbadresserna. När en användare begär en sida kör Django igenom varje sökväg, i ordning, och stannar vid den första som matchar den begärda webbadressen. (Om ingen av dem matchar anropar Django en 404-vy i specialfall.) Detta går blixtsnabbt, eftersom sökvägarna sammanställs till reguljära uttryck vid laddningstiden.
När ett av URL-mönstren matchar anropar Django den givna vyn, som är en Python-funktion. Varje vy får ett request-objekt - som innehåller metadata för begäran - och de värden som fångats i mönstret.
Om en användare till exempel begärde URL:en ”/articles/2005/05/39323/”, skulle Django anropa funktionen news.views.article_detail(request, year=2005, month=5, pk=39323)
.
Skriv dina synpunkter¶
Varje vy är ansvarig för att göra en av två saker: Returnera ett HttpResponse
-objekt som innehåller innehållet för den begärda sidan, eller skapa ett undantag som Http404
. Resten är upp till dig.
I allmänhet hämtar en vy data enligt parametrarna, laddar en mall och renderar mallen med de hämtade data. Här är ett exempel på en vy för year_archive
från ovan:
nyheter/views.py
¶from django.shortcuts import render
from .models import Article
def year_archive(request, year):
a_list = Article.objects.filter(pub_date__year=year)
context = {"year": year, "article_list": a_list}
return render(request, "news/year_archive.html", context)
I det här exemplet används Djangos mallsystem, som har flera kraftfulla funktioner men strävar efter att vara tillräckligt enkelt för att icke-programmerare ska kunna använda det.
Utforma dina mallar¶
Koden ovan laddar mallen news/year_archive.html
.
Django har en sökväg för mallar, vilket gör att du kan minimera redundans bland mallar. I dina Django-inställningar anger du en lista över kataloger som ska kontrolleras efter mallar med DIRS
. Om en mall inte finns i den första katalogen, kontrolleras den andra och så vidare.
Låt oss säga att mallen news/year_archive.html
hittades. Så här kan det se ut:
nyheter/templates/nyheter/year_archive.html
¶{% extends "base.html" %}
{% block title %}Articles for {{ year }}{% endblock %}
{% block content %}
<h1>Articles for {{ year }}</h1>
{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}
Variablerna omges av dubbla hakparenteser. {{ article.headline }}
betyder ”Skriv ut värdet för artikelns rubrikattribut.” Men prickar används inte bara för attributuppslagning. De kan också användas för uppslagning av ordboksnycklar, indexuppslagning och funktionsanrop.
Observera att {{ article.pub_date|date:"F j, Y" }}
använder en Unix-liknande ”pipe” (tecknet ”|”). Det här kallas ett mallfilter och är ett sätt att filtrera värdet på en variabel. I det här fallet formaterar datumfiltret ett Python datetime-objekt i det angivna formatet (som finns i PHP:s datumfunktion).
Du kan kedja ihop så många filter som du vill. Du kan skriva custom template filters. Du kan skriva :doc:``custom template tags </howto/custom-template-tags>`, som kör anpassad Python-kod bakom kulisserna.
Slutligen använder Django konceptet ”template inheritance”. Det är vad {% extends "base.html" %}
gör. Det betyder ”Ladda först mallen som heter ’base’, som har definierat ett gäng block, och fyll blocken med följande block.” Kort sagt, det gör att du dramatiskt kan minska redundansen i mallar: varje mall behöver bara definiera det som är unikt för den mallen.
Så här kan mallen ”base.html” se ut, inklusive användningen av statiska filer:
mallar/base.html
¶{% load static %}
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<img src="{% static 'images/sitelogo.png' %}" alt="Logo">
{% block content %}{% endblock %}
</body>
</html>
Förenklat definierar den webbplatsens utseende och känsla (med webbplatsens logotyp) och ger ”hål” som underordnade mallar kan fylla. Detta innebär att en omdesign av webbplatsen kan göras genom att ändra en enda fil - basmallen.
Det låter dig också skapa flera versioner av en webbplats, med olika basmallar, samtidigt som du återanvänder barnmallar. Djangos skapare har använt denna teknik för att skapa slående olika mobilversioner av webbplatser genom att bara skapa en ny basmall.
Observera att du inte behöver använda Djangos mallsystem om du föredrar ett annat system. Även om Djangos mallsystem är särskilt väl integrerat med Djangos modellager, finns det inget som tvingar dig att använda det. För den delen behöver du inte heller använda Djangos databas-API. Du kan använda ett annat databasabstraktionslager, du kan läsa XML-filer, du kan läsa filer från disken eller vad du vill. Varje del av Django - modeller, vyer, mallar - är frikopplad från nästa.
Detta är bara ytan¶
Detta har bara varit en snabb överblick över Djangos funktionalitet. Några mer användbara funktioner:
Ett caching-ramverk som integreras med memcached eller andra backends.
Ett syndication-ramverk som låter dig skapa RSS- och Atom-flöden genom att skriva en liten Python-klass.
Fler attraktiva automatiskt genererade adminfunktioner - den här översikten har knappt skrapat på ytan.
Nästa steg är att du laddar ner Django, läser handledningen och går med i gemenskapen. Tack för ditt intresse!