Aus Linux-Magazin 04/2009

Webentwicklung mit Django

© Cheryl Ann Quigley, Fotolia.com

Das Geizen mit Entwicklungszeit ist das erklärte Ziel des Webframeworks Django. Es enthält leistungsfähige Automationen und reizt das Don’t-repeat-yourself-Prinzip voll aus.

Wie zügig sich die Programmieraufgaben des Linux-Magazin-Wettbewerbs aus Heft 10/08 mit dem High-Level-Python-Framework Django lösen lassen, hat Entwickler Douglas Napoleone für das Linux-Magazin auf Video dokumentiert ([1], [2]). Das Rapid-Application-Development-Kit entstand 2003 als internes Projekt der World Company, eines News- und Multimediaportals in Kansas [3]. Die Firma gab das Kit im Sommer 2005 als Open-Source-Software frei. Im September 2008 erreichte Django Version 1.0.

Die Zutaten

Django enthält einen Object-Relational-Mapper, der vom eingesetzten Datenbank-Backend abstrahiert. SQL steht als Alternative trotzdem zur Verfügung. Ein Administrations-Interface, das beispielsweise die Benutzer einer Django-Anwendung verwaltet, liegt fertig bei. Anders als bei vielen Webframeworks ist bei Django das Mapping der URLs auf Sprachobjekte nicht festgelegt. Der Entwickler definiert es vielmehr mit regulären Ausdrücken. So erhält der Besucher aussagekräftige Internetadressen, ohne dass sich für die Software-Achitektur daraus Einschränkungen ergeben. Eine erweiterbare Template-Sprache trennt Anwendungslogik und Seitengestaltung.

Django bindet außerdem Memcached oder andere Cache-Lösungen ein. Ein Syndikation-Framework erleichtert das Erzeugen von RSS und Atom-Feeds, die Sprachunterstützung bietet neben Übersetzungs-Strings auch Einhängepunkte für sprachspezifische Funktionen.

Erfolgsrezept

Seit einigen Jahren gilt das Model-View-Controller-Pattern als der Königsweg in der Webentwicklung. Dabei sorgt die Model-Rolle für Daten und Informationen, die View-Rolle übernimmt die Anzeige, die Controller-Komponente ist dagegen für die Interaktion mit dem Benutzer zuständig. Django setzt das MVC-Design um, lediglich bei der Terminologie erlaubt es sich Freiheiten: Controller heißen Views, die Views Templates.

Die Entwicklung einer Webanwendung mit Django folgt meist einem festen Schema (Abbildung 1): Anfangs erstellt der Entwickler, unterstützt von Skripten, das Gerüst. Dann definiert er über Python-Objekte Models. Die externe Datenbank bringt Django dann automatisch auf den aktuellen Stand. URL-Mapper und Views legen schließlich fest, wie die Webanwendung auf bestimmte URLs reagiert, Templates sorgen für das Design.

Abbildung 1: Aus der Architektur des Django-Framework ergibt sich bei der Entwicklung ein typischer Workflow.

Abbildung 1: Aus der Architektur des Django-Framework ergibt sich bei der Entwicklung ein typischer Workflow.

Für Django gibt es ein plattformunabhängiges Paket [4]. Für die Entwicklung steht damit ein leichtgewichtiger Webserver bereit. Auf Produktivsystemen läuft Django mit dem Apache-Modul »mod_python« [5], eine detaillierte Installationsanleitung bietet [6].

Loslegen

Der Befehl »python django-admin.py startproject django_lesezeichen« legt das Projekt »django_lesezeichen« an. Der Aufruf des Django-Admin erzeugt im aktuellen Ordner ein Wurzelverzeichnis mit einer Struktur, die bei allen Django-Projekten gleich ausfällt. Darin liegen die Datei »_init__.py«, die es als Python-Package identifiziert, sowie das Kommandozeilenskript »manage.py«, das für administrative Aufgaben wie das Anlegen neuer Projekte oder den Start des Webservers zuständig ist. »settings.py« enthält die Konfiguration für das Projekt, »urls.py« das URL-Mapping.

Django unterstützt mehrere Datenbanksysteme wie SQLite, MySQL, PostgreSQL oder Oracle. Das Beispiel in diesem Artikel benutzt SQLite. Dazu ist »settings.py« wie in Listing 1 anzupassen. In der Variablen »ADMINS« ist mindestens ein Superuser-Konto zu hinterlegen.

Listing 1:
»settings.py« (1)
01 DEBUG = True
02 TEMPLATE_DEBUG = DEBUG
03 ADMINS = (
04     # ('<I>Name<I>', '<I>E-Mail-Adresse<I>'),
05 )
06 MANAGERS = ADMINS
07 DATABASE_ENGINE = 'sqlite3'     # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'
08 DATABASE_NAME = 'lesezeichendb' # oder Pfad zur Datenbankdatei
09 DATABASE_USER = ''                      # bei sqlite3 leer
10 DATABASE_PASSWORD = ''                  # bei sqlite3 leer
11 DATABASE_HOST = ''                      # leerer String bedeutet 'localhost ', bei sqlite3 ohne Bedeutung
12 DATABASE_PORT = ''                      # leerer String bedeutet 'default', bei sqlite3 ohne Bedeutung
13  (...)

Der Aufruf »python manage.py syncdb« erzeugt dann die Datenbank inklusive der Standardtabellen, die Django benötigt. Statusmeldungen zeigen, ob dies gelungen ist. »python manage.py runserver« startet den Django-eigenen Entwicklungs-Webserver, der standardmäßig auf Port 8000 lauscht. Hat der Entwickler das Projekt lediglich initialisiert, aber noch keinen eigenen Code geschrieben, liefert er ähnlich wie Apache die Willkommensseite aus Abbildung 2 aus.

Abbildung 2: Django enthält einen eigenen Webserver für die Entwicklung, den »python manage.py runserver«, der ohne Installationsaufwand startet.

Abbildung 2: Django enthält einen eigenen Webserver für die Entwicklung, den »python manage.py runserver«, der ohne Installationsaufwand startet.

Zugehörigkeit klären

Django unterscheidet zwischen Projekten und Applikationen. Ein Projekt entspricht einer Website, die mehrere Applikationen, etwa einen Blog oder ein Umfragemodul, enthalten kann. Eine Applikation darf mehreren Projekten angehören. Eine Applikation lässt sich auch als Container für Views und Datenmodelle auffassen. Der Befehl »python manage.py startapp lesezeichen« erzeugt die Applikation »lesezeichen«. Er legt ein Verzeichnis »lesezeichen« im Projektverzeichnis an, das außer der Python-typischen Datei »__init__.py« noch »views.py« und »models.py« enthält. Diese Dateien definieren Views und Models der Webanwendung.

Objektiv

Die meisten Webanwendungen kommunizieren über SQL mit der Datenbank. Django nutzt dagegen Python-Klassen, die vom Datenbank-Backend abstrahieren. Die Lesezeichen-Sammlung braucht folgende Datenbank-Objekte: »User« mit den Attributen »ID«, »nutzername«, »passwort« und »email«, »Link« mit den Feldern »ID« und »URL« sowie »Lesezeichen« mit den Eigenschaften »ID«, »titel«, »nutzer_id« und »link_id«.

Wie die Datenobjekte »models.py« zu definieren sind, zeigt Listing 2 beispielhaft für das URL-Objekt. Die erste Zeile enthält eine »import«-Anweisung für alle erforderlichen Django-Klassen. Die eigentliche Model-Klasse steht in Zeile 4. Die Klasse »Link()« erbt von »models.Model«, der Basisklasse für alle Model-Klassen. Sie enthält ein Feld mit »url« vom Typ »models.URLField«. Es ist als »unique« (eindeutig) gekennzeichnet. Außer dem speziellen Feldtyp »models.URLField« bietet Django die Standarddatentypen aus Tabelle 1.

Listing 2:
»models.py« (1)
01 from django.db import models
02 
03 # Create your models here.
04 class Link(models.Model):
05         url = models.URLField(unique=True)
06 
07         def __unicode__(self):
08                 return self.url

Die magische Methode »__unicode__()« in Zeile 7 gibt die Unicode-Repräsentation des Objekts zurück. Mit doppeltem Unterstrich beginnende und endende magische Methoden überladen in Python Standardfunktionen oder Operatoren. Django nutzt »__unicode__()« überall dort, wo eine Model-Instanz als gewöhnlicher String anzuzeigen ist.

Tabelle 1: Feldtypen
in Django

Wachgeküsst

Um das definierte Model in der Applikation »lesezeichen« nutzen zu können, muss der Entwickler die Applikation aktivieren. Dazu fügt er sie der Variablen »INSTALLED_APPS« in der Datei »settings.py« hinzu (Listing 3).

Ein Datenbank-Sync (»python manage.py syncdb«) erzeugt nun die Tabelle »URL«. Dieser Befehl kam bereits beim Initialisieren zum Einsatz. Der Entwickler ruft ihn immer dann auf, wenn er das Datenmodell verändert hat.

Listing 3:
»settings.py« (2)
01 INSTALLED_APPS = (
02     'django.contrib.auth',
03     'django.contrib.contenttypes',
04     'django.contrib.sessions',
05     'django.contrib.sites',
06     'django_lesezeichen.lesezeichen',
07 )

Interaktiv

Um das Datenbank-API von Django kennenzulernen, ist es am besten, es anfangs auf der interaktiven Python-Kommandozeile auszuprobieren, die »python manage.py shell« startet. Zurerst importiert »from lesezeichen.models import *« das eben definierte Datenmodel. »link = Link(url=”)« erzeugt eine neue Instanz der Klasse »Link«, der Aufruf der Methode »link.save()« überträgt den Link aus dem Arbeitsspeicher endgültig in die Datenbank.

»link« gibt den Inhalt des URL-Felds zurück, eine Neuzuweisung »link.url=”« verändert ihn, ein Aufruf der »save()«-Methode überträg die Änderung in die Datenbank. Folgende Zeilen geben alle gespeicherten Link-Objekte zurück:

links = Link.objects.all()
for link in links:
print link.url

Um ein Objekt anhand seiner ID abzufragen, gibt man »Link.objects.get(id=1)« ein, »link.delete()« löscht ein Link-Objekt, » Link.objects.count()« gibt die Anzahl der in der Datenbank verbliebenen Objekte zurück.

Weitere Modelle

Ein User-Model beinhaltet Django schon von Haus aus. Folgender Code auf der interaktiven Konsole importiert es:

from django.contrib.auth.models import User User.objects.all()

Die Ausgabe von »User.objects.all()« gibt bisher lediglich den bei der Konfiguration der Datenbank angelegten Superuser zurück.

Nun fehlt nur noch das Lesezeichen-Datenmodell. Ein Lesezeichen gehört einem User und enthält einen Link. Allerdings kann ein User mehrere Lesezeichen haben, ein Link soll für mehrere Benutzer zugänglich sein. Ein Lesezeichen steht also sowohl zu User als auch zu Link in einer Many-to-many-Relation. Der Python-Code aus Listing 4 erzeugt das dazu passende Datenmodell.

Zeile 1 importiert die User-Klasse. Die Lesezeichen-Klasse ab Zeile 11 enthält ein Textfeld »title« sowie Fremdschlüssel zum »User«- und »Link«-Model. Die magische Python Funktion »__unicode__()« gibt – wie schon in der Link-Klasse – den Inhalt im Klartext zurück. »python manage.py syncdb« schreibt das Model in die Datenbank.

Listing 4:
»models.py« (2)
01 from django.contrib.auth.models import User
02 from django.db import models
03 
04 # Create your models here.
05 class Link(models.Model):
06         url = models.URLField(unique=True)
07 
08         def __unicode__(self):
09                 return self.title
10 
11 class Lesezeichen(models.Model):
12         title = models.CharField(maxlength=200)
13         benutzer = models.ForeignKey(User)
14         link = models.ForeignKey(Link)
15 
16         def __unicode__(self):
17                 return self.title

Schützenhilfe für den Admin

In Django lassen sich nicht nur Benutzer und Systemobjekte mit dem mitgelieferten Administrations-Interface bearbeiten. Es kann vielmehr auch benutzerdefinierte Models verwalten. Um es zu aktivieren, ist Folgendes erforderlich:

  • In der Datei »settings.py« fügt der Entwickler
    den Eintrag »django.contrib.admin« zu der Variablen
    »INSTALLED_APPS«hinzu.
  • Wie nach jeder Aktivierung einer neuen Applikation
    synchronisiert er die Datenbank.
  • In der Datei »urls.py« entfernt er die
    Kommentarzeichen vor den von Django bereits angelegten
    Einträgen, die die URL »http://Domain/admin« zum
    Administrations-Interface weiterleiten. Listing 5 zeigt die
    Details.
Listing 5: »urls.py«
(1)
01 from django.conf.urls.defaults import *
02 
03 # Uncomment the next two lines to enable the admin:
04 from django.contrib import admin
05 admin.autodiscover()
06 
07 urlpatterns = patterns('',
08     # Example:
09     # (r'^mysite/', include('mysite.foo.urls')),
10 
11     # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
12     # to INSTALLED_APPS to enable admin documentation:
13     # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
14 
15     # Uncomment the next line to enable the admin:
16     (r'^admin/(.*)', admin.site.root),
17 )

Nach dem Neustart des Development-Servers kann sich der Entwickler mit dem Superuser-Account unter der URL »http://127.0.0.1:8000/admin/« im Admin-Interface anmelden.

Das Interface zeigt bis jetzt erst die Einstellungen für »Groups«, »User« und »Sites«. Eine Datei »admin.py« im Projektverzeichnis mit folgendem Inhalt fügt das Link- und Lesezeichen-Model hinzu:

from lesezeichen.models import Link, Lesezeichen
from django.contrib import admin
admin.site.register(Link)
admin.site.register(Lesezeichen)

Nach einem Neustart des Servers und Neuladen der Seite lassen sich die beiden vom Entwickler definierten Modelle über das Administrations-Interface verwalten (Abbildung 3).

Nun verwaltet das Administrations-Interface sämtliche Inhalte der Link-Datenbank. Einen Überblick über die zahlreichen weiteren Funktionen des Admin-Interface gibt [7].

Abbildung 3: Verwaltung gratis: Anders als Ruby on Rails liefert Django ein Administrations-Interface, das sich auch zur Verwaltung der Datenbank eignet, fix und fertig mit.

Abbildung 3: Verwaltung gratis: Anders als Ruby on Rails liefert Django ein Administrations-Interface, das sich auch zur Verwaltung der Datenbank eignet, fix und fertig mit.

Ansichtssache

Die Model-Komponente für die Lesezeichenverwaltung ist fertig. Nun fehlen noch Views, in klassischer Terminologie Controller, und die Templates, die außerhalb des Django-Umfelds Views heißen. Beim Aufruf einer URL läuft unter Django folgendes Schema ab: Das Framework sucht in »urls.py« nach einem Muster, also einem regulären Ausdruck, der auf die URL passt und diese mit einer View verbindet. Die passende View-Komponente greift auf die Datenbank zu und erzeugt aus einem Template eine HTML-Seite, die sie an den Browser sendet.

Eine View ersetzt die Standard-Willkommensseite beim Aufruf des Server-Root durch eine eigene Seite. Dazu verbindet eine Addressmapping-Regel eine Einsprungs-URL mit einer Python-Funktion (Listing 6).

Abbildung 4: Django setzt das etablierte Model-View-Controller-Schema um, wenn auch mit Eigenheiten bei der Namengebung. Eine Besonderheit ist dagegen das benutzerdefinierte URL-Mapping.

Abbildung 4: Django setzt das etablierte Model-View-Controller-Schema um, wenn auch mit Eigenheiten bei der Namengebung. Eine Besonderheit ist dagegen das benutzerdefinierte URL-Mapping.

Wie zu sehen ist, definiert der Entwickler das URL-Mapping anhand der Python-Tabelle »urlpatterns«, die Tupels im Format »(URL, View)« enthält. »r’String’« kennzeichnet sie als reguläre Ausdrücke. Vor der eigentlichen Mapping-Definition importiert die Datei noch einige Standardklassen, zum Beispiel »lesezeichen.views« in Zeile 2, um auf die Views zugreifen zu können, die in »views.py« definiert sind.

In Listing 6 gibt es nur eine einzige Zuordnung: Zeile 8 weist jede Webadresse außer der weiter oben deklarierten URL »admin/« der View »hauptseite« zu. Eine genaue Beschreibung des Python-Moduls »re« für reguläre Ausdrücke steht in der Python-Online-Dokumentation [8].

Listing 6: »urls.py«
(2)
01 from django.conf.urls.defaults import *
02 from lesezeichen.views import *
03 
04 # Uncomment the next two lines to enable the admin:
05 from django.contrib import admin
06 admin.autodiscover()
07 
08 urlpatterns = patterns('',
09     # Example:
10     # (r'^django_lesezeichen/', include('django_lesezeichen.foo.urls')),
11 
12     # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
13     # to INSTALLED_APPS to enable admin documentation:
14     # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
15 
16     # Uncomment the next line to enable the admin:
17     (r'^admin/(.*)', admin.site.root),
18 
19         # Eintrittspunkt für unsere Lesezeichenverwaltung
20         (r'^$', hauptseite),
21 )

Die richtige Perspektive

Eine View ist eine reguläre Python-Funktion. Listing 7 definiert in »views.py« die Funktion »hauptseite()«, die in »urls.py« bereits zugewiesen ist. Als Parameter nimmt die Funktion die Browseranfrage (»request«) entgegen und gibt die an den Browser zu sendende Antwort (»response«) zurück. Das kann eine HTML-Seite sein oder eine Umleitung, eine 404-Fehlernachricht, ein XML-Dokument oder ein Bild. In der View selbst befindet sich die Logik für das Erzeugen der Antwort auf die HTTP-Anfrage.

Das Beispiel generiert die Antwortsseite mit der Funktion »render_to_response()« und bindet so das Django-Templatesystem ein. Der erste Parameter nennt das Template, der zweite übergibt ein Objekt vom Typ »RequestContext«, welches Zeile 5 »variablen« zuweist.

Listing 7:
»views.py« (1)
01 from django.template import RequestContext
02 from django.shortcuts import render_to_response
03 
04 def hauptseite(request):
05         variablen = RequestContext(request,{
06                 'head_title' : 'Django Lesezeichen',
07                 'page_title' : 'Willkommen zu Django Lesezeichen',
08                 'page_body' : 'Seite um Lesezeichen zu speichern und zu sharen'
09                 } )
10         return render_to_response('hauptseite.html', variablen)

Musterschüler

Beim Schreiben von Webanwendungen kehren häufig bestimmte Muster wieder. Für die wichtigsten Aufgaben bietet Django daher fertige, Generic Views genannte Bausteine an. Sie stellen in Django fertigen Code für so unterschiedliche Dinge wie Redirect, Listen oder Oberflächen zum Editieren von Datenbankinhalten bereit. Wie bei gewöhnlichen Views sorgen Templates für ein konfigurierbares Aussehen. Weitere Informationen zu Generic Views sind unter [9] zu finden.

Vorgeformt

Django enthält eine Template-Sprache, die außer Platzhaltern Flusssteuerungs-Anweisungen und vor allem das Konzept der hierarchischer Vererbung, wie es aus der objektorientierten Programmierung bekannt ist, unterstützt. Für bessere Übersicht sollten Templates in einem eigenen Unterverzeichnis liegen. Dies muss der Entwickler in »settings.py« Django bekannt machen:

import os.path
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'))

Listing 8 zeigt eine einfache Template-Datei für die bereits erstellte View »hauptseite«. Sie enthält lediglich ein HTML-Grundgerüst sowie die drei Variablen »head_title«, »page_title« und »page_body«, erkennbar an den doppelten geschweiften Klammern. Ihren Inhalt übergibt die View mit einem »RequestContext«-Objekt. Das Template vervollständigt die einfache Django-Anwendung so weit, dass der Browser eine, wenn auch weitgehend statische Seite anzeigt.

Etwas tiefer in die Funktionsweise des Django-Framework führt das Programmieren einer benutzerspezifischen Seite ein, die die Liste der Lesezeichen des eingeloggten Anwenders anzeigt. Wieder stellt eine View-Komponente die Programmlogik zur Verfügung. Den hier erzeugten Text rendert Django erneut in ein Template. Der Benutzer soll die Seite über die URL »http://Hostname/benutzer/Benutzername« aufrufen können.

Listing 8:
»hauptseite.html«
01 <html>
02   <head>
03     <title>{{ head_title }}</title>
04   </head>
05   <body>
06     <h1>{{ page_title }}</h1>
07     <p>{{ page_body }}</p>
08   </body>
09 </html>

Die URL enthält diesmal eine dynamische Komponente, die die View-Komponente als Parameter erhalten soll. Mit regulären Ausdrücken im Mapping ist dies leicht zu erreichen. Listing 9 zeigt die erweiterte Version von »urls.py«, die letzte Zeile legt die neue View fest.

Der erste Teil des regulären Ausdrucks erkennt die Pfadkomponente »benutzer/«. »w+« fängt alle folgenden alphanumerischen Zeichen ab. Die Klammern reservieren diesen Teil des regulären Ausdrucks als Parameter für die View »benutzer_seite«. Die Datei »views.py« definiert diese View (Listing 10).

Listing 9: »urls.py«
(3)
01 urlpatterns = patterns('',
02   # Example:
03   # (r'^django_lesezeichen/', include('django_lesezeichen.foo.urls')),
04 
05   # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
06   # to INSTALLED_APPS to enable admin documentation:
07   # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
08 
09   # Uncomment the next line to enable the admin:
10   (r'^admin/(.*)', admin.site.root),
11 
12   # Eintrittspunkt für die Lesezeichenverwaltung
13   (r'^$', hauptseite),
14   (r'^benutzer/(w+)/$', benutzer_seite),
15 )

Im Gegensatz zur statischen View »hauptseite« nimmt »user_page« außer dem »request« einen zweiten Parameter aus dem URL-Mapping entgegen.

Listing 10:
»views.py« (2)
01 from django.http import Http404
02 from django.template import Context, RequestContext
03 from django.shortcuts import render_to_response
04 from django.contrib.auth.models import User
05 
06 def benutzer_seite(request, benutzername):
07         try:
08                 benutzer = User.objects.get(username=benutzername)
09         except:
10                 raise Http404('Benutzer konnte nicht gefunden werden.')
11 
12         lesezeichen = benutzer.lesezeichen_set.all()
13 
14         variablen = Context({
15                 'benutzername': benutzername,
16                 'lesezeichen': lesezeichen
17         })
18 
19         return render_to_response("benutzer_seite.html", variablen)

Drum prüfe

Als Erstes prüft »User.objects.get()« in Zeile 8, ob der angefragte Benutzer in der Datenbank vorhanden ist. Ist dies nicht der Fall, löst dies eine Exception aus. Die »except«-Anweisung in Zeile 9 fängt sie ab und löst eine »Http404«-Fehlermeldung aus. Existiert der Benutzer dagegen, fragt Zeile 12 die Lesezeichen des Benutzers über das Attribut »lesezeichen_set« des Benutzerobjekts aus der Datenbank ab. Dabei handelt es sich nicht um ein benutzerdefiniertes Attribut. Vielmehr erkennt Django automatisch die Beziehungen zwischen den Datenmodellen und erzeugt eine Reihe von Attributen ohne Zutun des Entwicklers.

Die eben definierte View »benutzer_seite« lädt das Template »benutzer_seite.html« und übergibt ihm den Benutzernamen und die Lesezeichen des Benutzers über »variablen«. Der HTML-Code in Listing 11 benutzt Schleifen- und Flusssteuerungs-Befehle aus der Template-Sprache, um eine Lesezeichenliste anzuzeigen.

Listing 11:
»benutzer_seite.html«
01 <html>
02   <head>
03     <title>Django Lesezeichen - Benutzer: {{ benutzername }}</title>
04   </head>
05   <body>
06     <h1>Lesezeichen für {{ benutzername }}</h1>
07     {% if lesezeichen %}
08       <ul>
09         {% for lesez in lesezeichen %}
10           <li><a href="http://%20lesez.link.url%20">
11             {{ lesez.title }}</a></li>
12         {% endfor %}
13       </ul>
14     {% else %}
15       <p>Keine Lesezeichen gefunden.</p>
16     {% endif %}
17   </body>
18 </html>

Die Variable »lesezeichen« ist eine Liste von Objekten, die sich nicht direkt im Template ausgeben lässt. Zeile 7 überprüft zunächst, ob die Liste einen Inhalt hat. Ist dies der Fall, iteriert die Schleife von Zeile 9 bis 12 über die enthaltenen Elemente und gibt diese aus. Die Zeilen 10 und 11 betten dabei die Attribute »link.url« und »title« der Schleifenvariablen in HTML-Code ein, sodass eine Liste von Hyperlinks entsteht. Ist die Lesezeichenliste dagegen leer, gibt Zeile 15 eine Fehlermeldung aus (Abbildung 5).

Abbildung 5: Dynamisches HMTL: Die If-Anweisung im Template stellt fest, dass die Lesezeichen-Datenbank noch leer ist, und präsentiert dies als Meldung.

Abbildung 5: Dynamisches HMTL: Die If-Anweisung im Template stellt fest, dass die Lesezeichen-Datenbank noch leer ist, und präsentiert dies als Meldung.

Frage des Inhalts

Um die Schleife in den Zeilen 9 bis 12 in Aktion zu sehen, fehlt noch der entsprechende Datenbankinhalt. Am leichtesten lässt sich dieser über die interaktive Konsole eingegeben. Die nötigen Module importieren »from django.contrib.auth.models import User« und »from lesezeichen.models import *«.

Ein Benutzer existiert bereits, »benutzer = User.objects.get(id=1)« holt ihn aus der Datenbank. »link = Link.objects.get(id=1)« fragt das bereits angelegte Link-Objekt ab. Das Lesezeichen-Model, das Links einem Nutzer zuweist, ist aber noch leer, wie »benutzer.lesezeichen_set.all()« zeigt. Folgende Eingabe auf der Konsole erzeugt ein Lesezeichen-Objekt, weist also das Link-Objekt dem schon existierenden Benutzer zu:

lesezeichen = Lesezeichen(title='Linux Magazin',benutzer=benutzer,link=link)
lesezeichen.save()
Abbildung 6: Ist die Datenbank mit Inhalt gefüllt, gibt das Template ihn als unsortierte HTML-Liste aus.

Abbildung 6: Ist die Datenbank mit Inhalt gefüllt, gibt das Template ihn als unsortierte HTML-Liste aus.

»benutzer.lesezeichen_set.all()« gibt nun die Ausgabe »<Lesezeichen: Lesezeichen object>« zurück. Die Benutzerseite sieht nun wie in Abbildung 6 aus.

Stürmische Entwicklung

Django ist ein umfangreiches Framework, mit dem sich Webanwendungen in Windeseile realisieren lassen. Die hervorragende Online-Dokumentation [10] sowie die beiden Bücher [11] und [12] führen in den großen Funktionsumfang ein. Allerdings liegt Django 1.0 erst seit Kurzem vor. Manche Änderung am API enthalten die Bücher noch nicht. (pkr)

Infos
[1] Progammierwettbewerb, Django-Lösung 1: [https://www.linux-magazin.de/online_artikel/django_video_workshop_von_douglas_napoleone]

[2] Progammierwettbewerb, Django-Lösung 2: [https://www.linux-magazin.de/online_artikel/reloaded_django_video_workshop_von_douglas_napoleone]

[3] World-Company: [http://www2.ljworld.com]

[4] Django: [http://www.djangoproject.com/download/]

[5] Mod_Python: [http://docs.djangoproject.com/en/dev/howto/deployment/modpython/]

[6] Installationsanleitung: [http://docs.djangoproject.com/en/dev/intro/install/]

[7] Django-Admin: [http://docs.djangoproject.com/en/dev/ref/contrib/admin/]

[8] Reguläre Ausdrücke: [http://docs.python.org/lib/module-re.html]

[9] Generic Views: [http://docs.djangoproject.com/en/dev/ref/generic-views/]

[10] Online-Dokumentation: [http://docs.djangoproject.com]

[11] Adrian Horvay, Jacob Kaplan-Moss, “The Definitive Guide to Django: Web Development Done Right”: Apress, 2007

[12] James Bennett, “Django Projects”: Apress, 2008

Der Autor
Der Schüler Michael Schneider interessiert sich für viele Themen aus der Software-Entwicklung, etwa Webentwicklung, Designpatterns und Fragen der Software-Architektur.
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben