Views für die Kategorie
Bisher konnten nur Administratoren die Daten im Admin-Bereich einsehen. Nun stellen wir diese Inhalte über ein eigenes Frontend öffentlich bereit.
Dafür benötigen wir drei zentrale Komponenten:
Views, die Daten aus der Datenbank laden
URLs, über die diese Views erreichbar sind
Templates, die die Daten darstellen
Für jede Seite oder Funktionalität im Frontend sind daher mindestens folgende Schritte notwendig:
eine URL in
event_manager/events/urls.pydefinierendie passende View in
event_manager/events/views.pyimplementierenein Template erstellen, in dem die Daten gerendert werden
Möchten wir beispielsweise eine Detailansicht für ein Event bereitstellen, benötigen wir:
eine URL, unter der die Seite erreichbar ist
eine View, die das entsprechende Event aus der Datenbank lädt
ein Template, das die Daten darstellt
Ein einfaches Beispiel für eine URL ist:
http://127.0.0.1:8000/events
Diese könnte verwendet werden, um eine Liste aller Events anzuzeigen.
Funktionsbasiert oder klassenbasiert
In Django gibt es zwei grundlegende Arten, Views zu implementieren: funktionsbasierte Views (Function-Based Views, FBV) und klassenbasierte Views (Class-Based Views, CBV).
Funktionsbasierte Views sind einfach aufgebaut und bieten maximale Kontrolle über den Ablauf. Klassenbasierte Views hingegen stellen für häufige Anwendungsfälle (z. B. Listen- oder Detailansichten) bereits vorgefertigte Strukturen bereit und reduzieren so Boilerplate-Code.
Welche Variante sinnvoll ist, hängt vom konkreten Anwendungsfall ab.
Die Kategorien
Zunächst entwickeln wir eine Übersicht aller in der Datenbank gespeicherten Kategorien, also eine Kategorie-Listenansicht.
Die Views für die Kategorien implementieren wir dabei funktionsbasiert. Für die Events werden wir später die klassenbasierte Herangehensweise kennenlernen.
URLs
Legen wir die URLs für die Kategorie an. Erstmal wollen wir ja die Übersicht
der Kategorien darstellen.
Dazu tragen wir folgendes in die event_manager/events/urls.py ein:
urlpatterns = [
path("hello_world", views.hello_world, name="hello_world"),
path("categories", views.categories, name="categories"),
]
Wir haben also eine neue Pfad-Angabe in unseren urlpatterns. Wenn ein User
jetzt http://127.0.0.1/events/categories in seinen Browser eingibt, soll er
eine Übersicht aller Kategorien erhalten. Das erste Argument von path ist
der URL-Pfad (innerhalb der App events), das zweite Argument ist die
Funktionsreferenz auf views.categories, die von Django intern aufgerufen
wird und das dritte Argument ist ein Name, den wir später noch im Template
brauchen, um die Verlinkungen zu ermöglichen.
Die View gibt es noch nicht, deshalb kommt es aktuell auch noch zu einem Fehler.
Views
Erstellen wir jetzt die View für diese Route und tragen folgendes in event_manager/events/views.py ein:
from django.shortcuts import render
from .models import Event, Category
def categories(request):
"""Funktion View, die alle Kategorien auflistet.
/events/categories
"""
categories_list = Category.objects.all()
return render(request,
"events/categories.html",
{"categories": categories_list})
Zuerst holen wir uns mit all() alle Kategorien via dem objects-Manager
und weisen sie der Variable categories_list zu.
Danach rufen wir die Funktion render() auf, die drei Argumente erwartet:
das request-Objekt
den Pfad zum HTML-Template
der Context: das sind die Daten, die von der
Django Template Enginein das Template gerendert werden sollen. Diese Daten werden in einem sogenanntenContext-Dictionaryübergeben. Der Zugriff auf die Daten später im Template erfolgt via dem Dict-Schlüssel. D.h. wenn wir im Template auf die Kategorie-Objekte zugreifen wollen, sprechen wir sie mit Keycategoriesan.
Sehen wir uns jetzt an, wie das Template gerendert werden soll:
Templates
Damit unser Programm funtioniert, benötigen wir noch ein Template für die Ausgabe aller Kategorien. Die Django-Doku erklärt in einem Satz eigentlich ganz gut, was ein Template in diesem Sinne überhaupt ist:
A template is a text file. It can generate any text-based format (HTML, XML, CSV, etc.). A template contains variables, which get replaced with values when the template is evaluated, and tags, which control the logic of the template.
—Django Dokumentation, Templates
Es gibt in einem Template also Variablen, die Werte anzeigen können und Tags, die eine Logik mitbringen, um die Darstellung zu steuern.
Dazu legen wir im Verzeichnis event_manager/events ein neues Verzeichnis
namens templates an. In dieses Template-Verzeichnis kommt ein weiteres
Verzeichnis Namens events.
Best Practice: Templates organisieren
Standardmäßig sucht der Django-Templateloader in jeder Anwendung nach einem
Verzeichnis names templates, falls APP_DIRS in den den Template-Settings in der settings.py auf True gesetzt wurde.
Damit es bei Templates mit gleichen Namen nicht zu Verwechslungen kommt, ist es notwendig, einen Namespace für die Templates anzulegen.
Für gewöhnlich wiederholt man den Namen der App, in unserem Fall also events.
Wenn ein Django-Projekt an Größe zunimmt, ist es oft bequemer, alle Templates
an einem Ort zu verwalten, als sie in vielen verteilten Apps zu suchen.
Dazu gibt man in den settings.py in DIRS weitere Templatepfade an, in denen der
Template-Loader nach dem Namen eines Templates sucht. Wir sehen in diesem Buch davon ab.
Die Template-Stuktur innerhalb einer App nach der Best Practice ist <APP-NAME>/templates/<APP-NAME>
events
├───migrations
├───templates
└───events
Wir legen jetzt die Datei event_manager/events/templates/events/categories.html und füllen Sie mit diesem Inhalt.
Wir sehen hier jeweils ein Beispiel für einen Tag und für eine Variable:
<h1>Übersicht der Kategorien</h1>
<ul>
{% for category in categories %}
<li>
{{categoy.name}}
</li>
{% endfor %}
Der Tag ist der der for-Tag, der im Grunde einfach nur ein for-Loop ist,
wie man es aus Python kennt. Wir iterieren also über alle categories und
legen in jeder Iteration auch noch gleich einen li-Tag an. Tags erkennt man
immer an der geschweiften Klammer und der Prozentzeichen. Viele Tags haben
einen öffnenden und schließenden Teil.
Die Variable ist die Ausgabe des Kategorie-Namens mit {{category.name}}.
Variablen stehen in doppelten geschweiften Klammern und haben kein
Prozentzeichen.
Template Rendern
Wir haben gesehen, dass wir ein HTML-Gerüst erstellt hatten und dort dynamisch Daten hineingeschrieben haben.
Wem das gezeigte HTML fremd ist, der sollte mal kurz innehalten und sich die Definition einer ungeordneten Liste in HTML ansehen.
Wenn wir jetzt den runserver starten, sollten wir unter http://127.0.0.1:8000/events/categories die Kategorien in einer Liste sehen.