Django-Dokumentation

Django auf einen Blick

Das Django in der schnelllebigen Umgebung einer Zeitung entwickelt wurde, wurde es entworfen, um wiederkehrende Webentwicklungsaufgaben einfach und schnell zu gestalten. Hier findest du einen schnellen Überblick darüber, wie man mit Django eine Web-Applikation mit Datenbank schreibt.

Das Ziel dieses Dokumentes ist es, dir genug technische Details über Django zu vermitteln, ohne ein Tutorial oder eine Referenz zu sein – das findest du jedoch auch in der Dokumentation! Wenn du bereit bist, ein Projekt zu beginnen, kannst du dir zunächst das Tutorial ansehen, oder direkt zu der Detaildokumentation übergehen.

Das Modell entwerfen

Obwohl du Django auch ohne Datenbank verwenden kannst, kommt es mit einem objekt-relationalen Mapper, durch den du das Datenbanklayout direkt in Python definieren kannst.

Die Datamodell-Syntax bietet viele Wege, deine Modelle zu bschreiben – für nun 2 Jahre hat es geholfen, Datenbankschema-Probleme zu lösen. Hier ein kleines Beispiel:

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __unicode__(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)

    def __unicode__(self):
        return self.headline

Installiere es

Als nächstes führe das Django-CLI-Utility aus, um die Datenbank-Tabellen automatisch zu generieren:

manage.py syncdb

Der syncdb-Befehl geht alle deine Modelle durch und erzeugt die entsprechenden Tabellen in deiner Datenbank, sofern sie nicht schon vorhanden sind.

Genieße die Gratis-API

Django bietet dir eine große Python-API, um deine Daten zu verwenden. Du musst dafür keinen eigenen Code schreiben:

>>> from mysite.models import Reporter, Article

# Es gibt bis jetzt noch keine Reporter.
>>> Reporter.objects.all()
[]

# Lege einen neuen Reporter an.
>>> r = Reporter(full_name='John Smith')

# Speichere das Objekt in die Datenbank. Du musst save() explizit
# aufrufen.
>>> r.save()

# Nach dem Speichern, hat das Objekt eine ID.
>>> r.id
1

# Jetzt gibt es den neuen Reporter in der Datenbank.
>>> Reporter.objects.all()
[<Reporter: John Smith>]

# Felder werden als Attribute im Python-Objekt abgebildet.
>>> r.full_name
'John Smith'

# Django bietet dir eine vielfältige Query-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.

# Erzeuge einen neuen Artikel.
>>> from datetime import datetime
>>> a = Article(pub_date=datetime.now(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# Jetzt enthält die Datenbank diesen Artikel.
>>> Article.objects.all()
[<Article: Django is cool>]

# Article-Objekte verfügen über eine API, um Zugriff auf die
# entsprechenden Reporter-Objekte zu bekommen.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# Und umgekehrt können Reporter-Objekte durch die API ihre Artikel
# erreichen.
>>> r.article_set.all()
[<Article: Django is cool>]

# Die API folgt Beziehungen so weit wie du sie brauchst, wobei
# effiziente JOINs im Hintergrund ausgeführt werden.
# Hier werden sämtliche Artikel von denjenigen Reportern gefunden,
# deren Name mit "John" beginnt.
>>> Article.objects.filter(reporter__full_name__startswith="John")
[<Article: Django is cool>]

# Ändere ein Objekt indem du seine Attribute änderst und danach
# save() ausführst.
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Lösche ein Objekt mit delete().
>>> r.delete()

Eine dynamische Admin-Oberfläche: Warum sich nur mit einem Gerüst begnügen

Sobald deine Modelle angelegt sind kann Django automatisch eine professionelle und vollkommen einsatzfähige Administrations-Oberfläche bereitstellen. Also eine Web-Seite, die es angemeldeten Benutzern erlaubt, Objekte anzulegen, zu ändern und zu löschen. Alles, was du dafür machen musst, ist, dein Modell bei der Admin-Seite zu registrieren:

# In models.py...

from django.db import models

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)


# In admin.py im selben Verzeichnis ...

import models
from django.contrib import admin

admin.site.register(models.Article)

Die Idee hier ist, dass deine Seite von einem Team, einem Kunden oder einfach nur von dir selbst betrieben wird -- und du möchtest in der Regel keine eigene Backend-Oberfläche bauen müssen, nur um den Inhalt zu verwalten.

Ein üblicher Ablauf, wenn es darum geht Django-Applikationen zu erstellen, ist, zunächst die Modelle zu erzeugen und gleich danach die Admin-Seiten so schnell wie möglich einzurichten, damit dein Team (oder deine Kunden) die Datenbank befüllen können. Danach erst erstellst du den Teil, der die Daten nach aussen hin darstellt.

Designe deine URLs

Ein sauberes und einfaches URL-Schema ist ein wichtiges Detail einer qualitativ hochwertigen Webapplikation. Django macht dir das sehr einfach und zwingt dich nicht zu überflüssigen Dingen wie zum Beispiel einer .php- oder .asp-Erweiterung.

Um das URL-Schema für eine Applikation zu entwerfen, musst du spezielles Python-Modul genannt URLconf anlegen. Du kannst dieses Modul fast wie ein Inhaltsverzeichnis deiner Seite verstehen, das ein einfaches Mapping zwischen URLs und Callback-Funktionen in Python darstellt. URLconfs dienen auch dazu, URLs von Python-Code zu entkoppeln.

Hier ein kleines Beispiel für eine URLconf für das Reporter/Article- Beispiel von weiter oben:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^articles/(\d{4})/$', 'mysite.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
)

Dieser Code bindet URLs in Form von regulären Ausdrücken an Python-Callback-Funktionen ("views"). Die regulären Ausdrücke nutzen Gruppen, um Werte aus den URLs in Parameter umzuwandeln. Wenn ein Benutzer eine Seite anfragt, geht Django jedes Muster der Reihe nach durch und stoppt beim ersten, das der anfragten URL entspricht. (Wenn kein passendes Muster gefunden wird, ruft Django einen eigenen 404-View auf.)

Sobald einer dieser regulären Ausdrücke passt, importiert Django den entsprechenden View, der nicht weiter als eine einfach Python-Funktion ist. Jeder View bekommt ein Request-Objekt (welches die Metadaten des Requests enthält) und die Werte, die durch den regulären Ausdruck gefunden wurden, als Argumente übergeben.

Wenn ein Benutzer zum Beispiel die URL "/articles/2005/05/39323/" aufruft, würde Django mysite.views.article_detail(request, '2005', '05', '39323') aufrufen.

Schreibe die Views

Jeder View soll entweder ein HttpResponse-Objekt zurückgeben, das den Inhalt der angefragten Seite enthält, oder eine Exception (wie zum Beispiel Http404) werfen. Was bis dahin geschieht, ist ganz dir überlassen.

In der Regel lädt ein View Daten entsprechenden den Parametern des Requests, lädt ein Template und befüllt es mit den Daten. Hier ist ein Beispiel für den year_archive-View von oben:

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

Dieses Beispiel nutzt Djangos Template-System, das obwohl es sehr mächtig ist, dennoch versucht so einfach wie möglich zu bleiben, damit es auch von Nicht-Programmierern verwendet werden kann.

Entwerfe deine Templates

Der obere Code verwendet das news/year_archive.html-Template. Django verfügt über einen Template-Suchpfad, der es dir ermöglicht, Redundanzen innerhalb der Templates zu minimieren. In deinem Django-Einstellungen kannst du eine Reihe von Verzeichnissen angeben, die in diesem Suchpfad sein sollen. Wenn ein Template im ersten Verzeichnis nicht existiert, wird das nächste Verzeichnis durchsucht usw.

Gehen wir einmal davon aus, dass das news/article_details.html-Template gefunden wurde. So könnte das zum Beispiel aussehen:

{% 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 %}

Variablen werden von einem Paar geschwungener Klammern umschlossen. {{ article.headline }} bedeutet, "Gib den Wert des headline-Attributes des Artikels aus. Punkte werden jedoch nicht nur für Attribute verwendet: Sie können auch für dict-Schlüssel, Listen-/Tuppel-Indexes oder Funktionsaufrufe verwendet werden.

{{ article.pub_date|date:"F j, Y" }} im obrigen Beispiel verwendet eine aus Unix bekannte "pipe" (das "|"-Zeichen). Das wird hier als Template-Filter bezeichnet und ist eine Methode, um den Wert einer Variable zu filtern. Hier wird der date-Filter genutzt um ein Python-datetime-Objekt entsprechend einem angegebenen Format auszugeben (vergleichbar mit der "date"- Funktion in PHP; ja, es gibt auch gute Sachen in PHP).

Du kannst Filter aneinanderreihen wie du willst. Du kannst auch eigene Filter oder Templatetags schreiben, die deinen eigenen Python-Code im Hintergrund ausführen.

Django nutzt ein Konzept namens "Template-Vererbung": Das ist das, wofür das {% extends "base.html" %} da ist. Das bedeutet: "Lade zunächst das 'base'-Template, welches eine Reihe von Blöcken definiert hat, und fülle dieses Blöcke mit den Blöcken, die hier definiert sind." Kurz gesagt, das ermöglicht dir, Redundanzen stark zu minimieren. Jedes Template muss lediglich das definieren, was anders ist als überall anders.

So könnte zum Beispiel dieses "base.html"-Template aussehen:

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="sitelogo.gif" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

Es definiert das Aussehen deiner Seite (inklusive Logo) und bietet genug Platzhalter, die dann von erbenden Templates befüllt werden können. Dadurch kannst du das Design deiner Seite durch eine einzige Datei, dem Base-Template, ändern.

Das macht es auch einfach, mehrere Versionen einer Seite zu erstellen, die unterschiedliche Base-Templates dieselbe Subtemplate verwenden. Die Autoren von Django haben die Technik genutzt, um Handy-Versionen von Seiten zu erstellen, einfach indem sie ein neues Base-Template konstruiert haben.

Bitte beachte, dass du Djangos Template-System nicht verwenden musst, wenn du ein anderes System bevorzugst. Obwohl Djangos Template-System sehr gut mit dem Modell-Layer zusammenarbeitet, zwingt dich niemand dazu, das auszunutzen. Du muss auch nicht Djangos Datenbank-API nutzen. Du kannst eine andere Datenbank-Abstraktionsschicht nutzen, oder XML-Dateien auslesen, beliebige Dateien von der Festplatte lösen, oder was auch immer du willst. Jedes Teil von Django -- Modelle, Views und Templates -- ist unabhängig von den jeweils anderen.

Das war erst der Anfang

Das war lediglich ein kurzer Überblick über die Funktionen, die dir Django bietet. Hier noch ein kurzer Verweis auf weitere nützliche Features:

  • Ein Caching-Framework, das memcached oder andere Backends nutzt.
  • Ein Syndication-Framework, das das Erstellen von RSS- und Atom-Feeds nicht schwerer macht als das Schreiben einer kleinen Python-Klasse.
  • Eine ganze Reihe anderer toller Features der Admin-Overfläche -- dieser Überblick hat hier lediglich einen Vorgeschmack geboten.

Als nächstes, lade Django herunter, lies das Tutorial und werde Teil der Community. Danke für dein Interesse!