.. _create_views:
.. index::
single: Views
single: klassenbasierte Views
single: Request-Objekt
single: URLs
single: Template Namespacing
Views für die Kategorie
**************************************
Bis konnten nur Administratoren die Daten sehen. Wir wollen sie jetzt der Öffentlichkeit zur Verfügung stellen. Dazu benötigen wir einerseits die entsprechenden Views, die die Daten darstellen und andererseits die URLs, die auf die Seiten führen. Zusätzlich müssen noch die HTML-Templates erstellt werden.
Für jede Aktion/Webseite, die wir entwickeln wollen, müssen wir also (mindestens) die folgenden drei Schritte tun:
* URL in den urlpatterns von ``event_manager/events/urls.py`` anlegen
* die dazugehörige VIEW in den ``event_manager/events/views.py`` erstellen
* das entsprechende Template erstellen, in das die Daten gerendert werden.
Wenn wir also eine Detail-Ansicht eines Events ermöglichen wollen, müssen wir eine URL dafür anlegen, unter der diese Detailseite erreichbar ist. Wir müssen eine View anlegen, die aufgerufen wird und die nötigen Daten aus der Datenbank zieht. Und wir müssen ein Template anlegen, in das die Daten gerendert werden.
Ein URL könnte zum Beispiel sein: ``http://127.0.0.1:8000/events`` die uns alle Events auflistet.
.. admonition:: Funktionsbasiert oder klassenbasiert
In Django gibt es zwei Arten von Möglichkeiten, Views zu entwicklen: die ältere aber sehr mächtige Art und Weise ist die sogenannte ``function-based`` View, die View also als Funktion zu schreiben. Daneben gibt es für immer wiederkehrende Standardaufgaben noch die -sehr komfortable- klassenbasierte View.
Je nachdem, welches Problem gelöst werden soll, wählen wir zwischen den beiden.
View/Url/Template für die Übersicht aller Kategorien schreiben
---------------------------------------------------------------
Zuerst wollen wir eine Ausgabe aller bisher in der Datenbank hinterlegten Kategorien entwickeln.
URLs
......
Dazu tragen wir folgendes in die ``event_manager/events/urls.py`` ein:
.. code-block:: python
urlpatterns = [
path("hello_pingus", views.hello_pingus, name="hello_pingus"),
path("categories", views.list_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.list_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.
Views
.......
Erstellen wir jetzt die View für diese Route und tragen folgendes in ``event_manager/events/views.py`` ein:
.. code-block:: python
def list_categories(request):
"""Funktion View, die alle Kategorien auflistet.
http://127.0.0.1:8000/events/categories
"""
print("das Request Objekt: ", dir(request)) # Testen, dann löschen
print("verwendete HTTP-Methode: ", request.method) # Testen, dann löschen
categories = Category.objects.all()
return render(request, "events/category_list_simple.html",
{"categories": categories})
hier passiert folgendes:
* wir holen uns mit ``all()`` alle Kategorien via dem objects-Manager
* wir rufen die Funktion ``render()`` auf, die das request-Objekt und den Pfad zum HTML-Template als Argument erwartet. Als optionales Argument können wir noch den sogennannten Context übergeben: das sind die Daten, die von der ``Django Template Engine`` in das Template gerendert werden sollen. Diese Daten werden in einem sogenannten ``Context-Dictionary`` übergeben, der Zugriff auf die Daten erfolgt via dem Dict-Schlüssel.
.. admonition:: Das Request-Objekt
Jede View, sei sie funktions- oder klassenbasiert, erhält das Request-Objekt als Argument übergeben. Das Request-Objekt enthält alle möglichen Daten über den HTTP-Request wie ``GET-Daten`` und ``POST-Daten``, URL-Pfade oder gesendete Cookies. Mit ``request.method`` kann zum Beispiel die gewählte ``HTTP-Methode`` untersucht werden.
Mit ``print(dir(request))`` können wir das Request-Objekt auch untersuchen.
Mehr zum Request-Objekt findet sich in der Doku: ``_
.. admonition:: Print-Aufrufe in der View
Standardmäßig werden print-Aufrufe in einer View auf der Konsole ausgegeben. Das ist für die ersten Schritte in Ordnung. Später werden wir noch eine bessere Methode kennenlernen, nämlich das Loggen mit dem ``logging-Modul`` in Dateien.
Templates
...........
Damit unser Programm funtioniert, benötigen wir noch ein Template für die Ausgabe aller Kategorien.
Dazu legen wir im Verzeichnis ``event_manager/events`` ein neues Verzeichnis namens ``templates`` an. In dieses Template-Verzeichnis kommt ein weiteres Verzeichnis Namens ``events``.
.. admonition:: Template-Namespacing
Damit es bei Templates mit gleichen Namen nicht zu Verwechslungen kommt, ist es notwendig, einen Namespace für die Templates zu ermöglichen. Dies geschieht implizit durch das Anlegen der Ordnerstruktur.
Die Template-Stuktur ist ``/templates/``
.. code-block:: bash
events
├───fixtures
├───management
│ └───commands
├───migrations
├───templates
└───events
Wir legen jetzt die Datei ``event_manager/events/templates/events/category_list_simple.html`` und füllen Sie mit diesem Inhalt.
.. code-block:: html+django
Übersicht der Kategorien
{% for cat in categories %}
-
{{cat.name}}
{% endfor %}
Wenn wir jetzt den runserver starten sollten wir unter ``http://127.0.0.1:8000/events/categories`` die Kategorien in einer Liste sehen.
.. image:: /images/category_overview.png