Wiederverwendbare Django Apps - reusable apps

0 | 5976 Aufrufe
Sie können diese Wikiseite nach der Anmeldung auf Webmasterpro bearbeiten. Helfen Sie mit und verbessern Sie "Wiederverwendbare Django Apps - reusable apps" mit Ihrem Wissen!

Anzeige Hier werben

Artikelserie - Wiederverwendbarkeit von Django Applikationen

Dieser Artikel ist Teil einer Artikelserie rund um die Erstellung wiederverwendbarer Django Applikationen

Motivation

Bild zu Wiederverwendbare Django Apps - reusable apps

Die größte Motivation eine wiederverwendbare Applikation für Django zu schreiben sollte sein, dass Du diese in den meisten Projekten verwenden kannst ohne etwas an Ihr zu ändern. Hast Du erst einmal gelernt wiederverwendbare Applikationen zu schreiben und zu benutzen, wird es umso einfacher sein ein neues Projekt zu erstellen. Die Hauptaufgabe wird dann sein, die gewünschten Applikationen einzubinden und zu konfigurieren.

Grundlagen

Viele Entwickler tendieren dazu ein Projekt als eine einzige Applikation anzusehen. Das führt dazu, dass diese eine Applikation zu viele Funktionen übernimmt. Die Möglichkeit diese wiederzuverwenden, wird meistens erst im Nachhinein in Betracht gezogen. Deshalb sollte man die gesamte Seite lieber als ein Zusammenspiel von vielen Applikationen sehen. Eine übernimmt die Funktion der Benutzerverwaltung, eine weitere beinhaltet meinen Blog, die nächste wiederum kümmert sich um den Versand des Newsletters.

Um diese Ansicht eines Projektes zu bekommen solltest Du folgende Dinge im Kopf behalten:

  • Versuche mit einer Applikation nur eine Funktion zu implementieren.
  • Es macht nichts aus wenn Du viele Applikationen in einem Projekt einsetzt.
  • Schreibe die Applikationen so, dass auch andere Sie verwenden könnten. Auch wenn Du der einzige bist der Sie einsetzen wird, ist dieser Aspekt wichtig. Er hilft Dir zu erkennen welche Funktionen nicht in die Applikation gehören oder welche Teile Du besser konfigurierbar machen solltest.
  • Plane die Applikationen möglichst flexibel. Umso weniger Du die Nutzung mit zu speziellen Features einengst, umso besser kannst Du die Anwendung wiederverwenden.

Die Applikation

Wie schreibe ich nun solche Anwendungen? Im Prinzip genauso wie die, die Du bisher schon geschrieben hast. Der Unterschied ist nur, dass die einzelnen Funktionen in mehreren Applikationen untergebracht werden. Mach Dir zunächst klar, welche Funktionen Dein Projekt benötigt. Dann versuche diese in kleine Bereiche einzuteilen. Welche von den geplanten Funktionen hast Du bereits in einem anderen Projekt verwendet? Welche sehen danach aus, als ob man Sie in Zukunft nochmals verwenden könnte?

Sehen wir uns als Beispiel einen typischen Blog an. Welche Funktionen benötigt dieser? Klar, eine Möglichkeit Einträge zu verfassen, diese zu taggen und zu kommentieren. In eine Linksektion kommen die Verweise zu Seiten die keinen ganzen Artikel wert sind aber trotzdem für Deine Leser ganz interessant sein könnten. Außerdem brauchst Du ein Kontaktformular und ein Impressum.

Der oben angesprochene monolitische Ansatz wäre eine Applikation zu erstellen die die Models Entry, Link, Comment, Tag usw. enthält. Was aber wenn Du nun auch noch eine Bildergalerie auf die Seite einbinden möchtest? Dann muss diese Applikation wieder eine eigene Möglichkeit mitbringen Kommentare zu verfassen.

Wie bereits angesprochen ist die bessere Möglichkeit, die einzelnen Funktionen in eigenen Apps unter zu bringen. Eine für die Blogeinträge, eine für die Links, eine zum Taggen von anderen Models und wieder eine zum Kommentieren.

Die wiederverwendbare Applikation

Wie bekomme ich nun aber zum Beispiel eine wiederverwendbare Tag Applikation?

Zunächste: Was heißt in diesem Beispiel wiederverwendbar? Man sollte am besten jedes andere Model, egal ob es bereits existiert oder noch garnicht in Planung ist taggen können. Django bringt dazu eine nette Möglichkeit mit.

Generic Relations

Django legt für jedes installierte Model in der eingebauten contenttypes Applikation eine ID an. Zusammen mit dieser ID für ein Model und einer weiteren ID für die Instanz eines Models kann man auf beliebige Objekte eines Projektes verweisen. Dies machen wir uns zunutze um ein wiederverwendbares Tag Model zu schreiben.

Listing 1: tags/models.py  
Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.generic import GenericForeignKey

class Tag(models.Model):
    tag = models.CharField(maxlength=32)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()

    related_object = GenericForeignKey()

In Listing 1 ist eine Beispiel Implementation einer so genannten Generic Relation zu sehen. Dafür wird die oben erwähnte Technik verwendet. Zusätzlich zu den Verweisen auf den ContentType und die ID des Objekts wird ein GenericForeignKey zu gewiesen. Ist tag eine Instanz des Tag Models kann man nun über tag.related_object auf das getaggte Objekt zugreifen.

Wie man nun einen Blog Eintrag mit dem Stichwort Python versieht wird in Listing 2 beschrieben.

Listing 2  
Python
1
2
3
4
content_type = ContentType.objects.get_for_model(Entry)
id = blog_entry.pk
tag = Tag(tag="Python", content_type=content_type, object_id=id)
tag.save()

So lassen sich zwar nun beliebige Objekte taggen, besonders komfortabel ist das allerdings noch nicht. Um das ganze einfacher zu machen bietet Django an, in das zu taggende Model einen Art Rückverweis auf die Tags einzubinden.

Listing 3  
Python
1
2
3
4
5
6
from tags.models import Tag

class Entry(models.Model):
   # ...
   tags = GenericRelation(Tag)
   # ...

Mit Hilfe dieses Rückverweises kann man nun das erstellen eines Tags durch ein einfaches entry.tags.create(tag="Python") bewerkstelligen. Möchte man nun alle Tags eines Eintrages erfahren, schreibt man entry.tags.all(). Da die GenericRelation ein Queryset Interface zur Verfügung stellt, lässt sich die Suche auch weiter einschränken: entry.tags.filter(tag__startswith="P") gibt nur die Tags zurück die mit P beginnen.

Auch das darstellen aller Einträge mit dem selben Tag ist natürlich möglich. Listing 4 zeigt wies gemacht wird.

Listing 4  
Python
1
2
content_type = ContentType.objects.get_for_model(Entry)
entries = [tags.object for tags in Tag.objects.filter(tag="Python", content_type=content_type).select_related()]

Urls

Möchte man nun eine URL für die erstellten Models bereitstellen, sollte man auf jeden Fall vermeiden statische URLs wie /blog/entries/5/ zu verwenden. Eine elegantere Methode bietet Django mit den urlresolvers an.

Listing 5  
Python
1
2
from django.core.urlresolvers import reverse
url = reverse('myblog.views.entry_detail', kwargs={'id': 5})

Die Funktion reverse liefert dabei die Url zu dem angegeben view. Enthält die Url außerdem benannte Url Parameter können diese wie in Listung 5 als dictionary übergeben werden. Ändert man nun die Url in der entsprechenden urlconf Datei, so ändert sich auch der Rückgabewert der reverse Funktion.

Ein Problem gibt es nur wenn man zwei verschiedene Urls auf die gleiche view Funktion leitet. Um nun nicht wieder statische Url Angaben benutzen zu müssen, kann man einzelne Urls einen eindeutigen Namen geben. Listing 6 zeigt einen Ausschnitt einer urlconf Datei mit benannten Urls.

Listing 6  
Python
1
2
3
4
5
6
urlpatterns = patterns('',
    # ...
    url(r'/blog/entries/(?P<id>\d+)/$', 'myblog.views.entry_detail', name="blog-entry-id"),
    url(r'/blog/entries/(?P<slug>[-0-9a-zA-z]+)/$', 'myblog.views.entry_detail', name="blog-entry-slug"),
    # ...
)

Wichtig dabei ist, dass man für die Urls keine Python Tuples angibt sondern die Funktion url aufruft. Die Reihenfolge der Parameter sind die gleichen wie die Werte die man in einem Tupel angeben würde. Nur lässt sich z.B. der zusätzliche Parameter name angeben. Um nun die Url zu einem Blog Eintrag mit Hilfe eines slugs zu bekommen führt man die reverse Funktion mit dem Namen der Url als erstem Argument aus: reverse('blog-entry-slug', kwargs={'slug': 'reusable-django-apps'}).

Wiederverwendbare Applikationen im Netz

Durch den großen Vorteil den Django mit den wiederverwendbaren Applikationen bietet, lässt sich wie bereits erwähnt viel Zeit sparen. Und da diese ja wiederverwendbar sind, lassen sich die benötigten Anwendungen auch einfach von anderen Entwicklern übernehmen. Dazu hier ein einige bekannte Seiten über die man zu bereits existierenden Anwendungen gelangt:

Django Plugables ist ein Community Projekt auf dem man seine eigenen Applikationen eintragen und die anderer Entwickler finden kann.

Auch eine Suche bei Google Code nach Django sollte man einmal probiert haben. Dort sind sehr viele Projekte und Anwendungen zum Thema Django gehostet.

Um weiter Erfahrung mit der Entwicklung solcher Anwendungen zu sammeln ist stets zu empfehlen den Quellcode beliebter Apps zu studieren. Dort finden sich viele Kniffe, Tricks und Best Practices.


Wikiseite bearbeiten

Diese Seite kann von jedem registrierten Benutzer bearbeitet werden. Bisher haben 3 Personen an der Seite "Wiederverwendbare Django Apps - reusable apps" mitgewirkt.

Sie haben einen Fehler entdeckt oder möchten etwas ergänzen? Dann können Sie nach der Anmeldung "Wiederverwendbare Django Apps - reusable apps" hier bearbeiten.

Mitarbeiter
  • Ich bin zur Zeit Informatik Student und arbeite als freiberuflicher Programmierer. Die meisten Projekte verwirkliche ich mit Python und Django. Aber auch PHP zählt zu den Programmiersprachen die ich gelegentlich einsetze. Außerdem bin ich großer Fan von OpenSource und Linux.
  • Meine Schwerpunkte liegen im Bereich Grafikdesign, SEO und Management. Seit sieben Jahren bin ich als Geschäftsführer der Team23 GbR tätig, die Webdesign in Augsburg anbietet, sowie Webmasterpro.de betreut.
  • Kinderturnen - Sport Spiele für Kinder