.. _first_project: .. index:: single: manage.py single: django-admin single: Projektstruktur single: Testserver single: Installation Das Projekt erstellen *********************** Wir wollen nun ein Projekt anlegen. Unser Beispielprojekt soll ein Event-Manager werden, deshalb werden wir das Projekt ``event_manager`` nennen. Ein **Projekt** ist ein Container für sogenannte **Apps**. Jede Aktion, die in unserem Projekt abgearbeitet wird, findet in einer App statt. Apps sind also die **Systemkomponenten** im Djangosystem. Apps sind erstmal nichts weiter als Verzeichnisse, in denen wir unseren Python-Code schreiben und damit die Geschäftsprozesse und Domain-Models definieren. Projekt Event-Manager ============================ Generell ist es eine gute Idee, sich vor Beginn ein paar Gedanken zum Projekt zu machen. Zum Beispiel wer die Akteure sind, die am Projekt beteiligt sind. Für diese Aufgabe bietet sich zum Beispiel das **Use-Case-Diagram** an. Es zeigt die am System beteiligten **Akteuere** und die **Aktionen**, die sie innerhalb des Systems durchführen können. Alles, was außerhalb des Systems liegt, ist für das Projekt (System) irrelevant. Um sich ein Bild von unserem Projekt zu machen, habe ich hier ein Use-Case-Diagram angefertigt: .. image:: /images/use_case_event_manager.png Wir unterscheiden zwischen **Usern**, die Events anlegen und verwalten können, und einem **Admin**, der die Anwendung verwaltet. Dieser Admin steht für eine Gruppe von Personen mit Administrations- und Verwaltungsrechten, zum Beispiel einem Moderator. Diese Mitarbeiter können beispielsweise Event-Kategorien verwaltet, was einfachen Usern nicht möglich sein wird. Wenn Events von Usern eingetragen werden, müssen sie validiert werden, zum Beispiel, ob das Datum des Events auch tatsächlich in der Zukunft liegt oder ob der Titel des Events nicht nur aus Ziffern besteht. Mehr zum Use-Case-Diagramm findet sich zum Beispiel auf der Wikipedia: ``_ Der Django-Admin ================== Im Zuge der Django-Installation wurde auch ein kleines Helfertool mitgeliefert, um bequem neue Django-Projekte anzulegen und zu verwalten: Das Programm ``django-admin``. Die Eingabe von: .. code-block:: python (eventenv) django-admin liefert uns u.a. eine Übersicht aller Befehle, die wir damit auführen können: .. code-block:: python [django] check compilemessages createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata makemessages makemigrations migrate runserver sendtestemail shell showmigrations sqlflush sqlmigrate sqlsequencereset squashmigrations startapp startproject test testserver Für uns ist erstmal nur der Befehl ``startproject`` wichtig. Mit diesem Befehl erstellt man nämlich ein Django-Projekt. Das ist erstmal nicht viel mehr als ein Verzeichnis mit ein paar Unterordnern und Python-Dateien. ein Projekt mit django-admin erstellen ======================================= Das virtuelle Environment ist angelegt, Django ist im virtuellen Environment installiert, wir wollen nun ein Django-Projekt erstellen. .. admonition:: Was ist ein Django-Projekt? Ein Projekt im Sinne von Django ist ein übergeordneter Container, in dem sogenannte Apps verwaltet werden. Nehmen wir an, wir wollten ein Webshop wie Amazon entwickeln, der neben der eigentlichen Shop-Software zusätzlich noch einen Blog hat, eine User-Verwaltung, einen Datenimporter und eine Schnittstelle zu einer externen Waren-Datenbank hat. Das Projekt im Sinne von Django wäre dann der Webshop (Haupt-Domäne), die einzelnen Unterbereiche wie die Shop-Software, die User-Verwaltung oder der Blog wären die einzelnen Apps. .. admonition:: Was genau macht django-admin startproject? ``startproject`` ist ein sogenanntes Kommando des ``django-admin``-Tools. Wir hatten gesehen, dass es viele weitere Kommandos gibt, die wir später im Buch auch noch teilweise nutzen werden. ``startproject`` zum Beispiel erstellt zum einen die nötige Verzeichnisstruktur für ein Projekt, zum anderen werden die wichtigsten Dateien generiert. Wir wechseln also mit ``cd`` in das Verzeichnis ``event_project/event_manager`` und führen hier ``django-admin`` mit dem Subkommando ``startproject``, gefolgt von dem gewünschten Namen des Projekts auf und abschließend einem Punkt: .. code-block:: python (eventenv) cd django_projects/event_project/event_manager/ (eventenv) django-admin startproject event_manager . Unsere **Projektstruktur** sollte jetzt wie folgt aussehen: .. code-block:: shell ├── django_projects └── event_project └── event_manager ├── manage.py └── event_manager ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py └── requirements.txt └── requirements.in └── requirements-dev.txt └── requirements-dev.in └── README.md └── .gitignore Der Einfachheithalber werden in Zukunft alle Verzeichnisangaben in diesem Buch von dem Verzeichnis ``event_project`` aus gehen. D.h., wenn wir uns also auf die Datei ``settings.py`` beziehen, wäre die Pfadangabe ``event_manager/event_manager/settings.py``. Die Angabe von ``django_projects/event_project`` sparen wir uns ab jetzt. Ja, ihr seht richtig: es gibt ein äußeres ``event_manager`` und ein inneres ``event_manager``-Verzeichnis, welches durch den ``startproject``-Befehl angelegt wurde. .. admonition:: Inneres und Äußeres Es gilt als althergebrachte Django-Konvention, dass das **äußere Verzeichnis** den gleichen Namen trägt wie das **innere**. **Das muss aber nicht so sein!** Es macht den Anschein, dass immer mehr Entwickler mit dieser alten Konvention brechen. Häufig sieht man auch solche Strukturen: .. code-block:: shell . └── event_manager ├── manage.py └── project ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py Um diese zu erreichen, hätten wir das Verzeichnis ``event_manager`` manuell anlegen und in diesem dann ``django-admin startproject project .`` ausführen müssen. Der Grund ist, dass der selbe Namen von innerem und äußeren Verzeichnis manchmal zur Verwirrung führt. Da in dem inneren ``event_manager`` die projekt-bezogenen Dateien liegen, macht es durchaus Sinn, diesen Ordner zum Beispiel ``project`` (oder ähnlich) zu nennen. Wir halten uns in diesem Buch allerdings an den eher konventionellen Weg und bleiben bei der gleichen Benennung von innerem und äußeren Verzeichnis. .. admonition:: Good Practice Django-Admin ``startproject`` erstellt eine Verzeichnis-Struktur und legt diverse Dateien an. Dies könnte man natürlich auch manuell ohne ``startproject`` machen. In der Praxis ist aber der Weg über ``startproject`` der schnellere, sicherere und elegantere Weg, ein ``Django-Projekt`` zu erstellen. Es wurden nun einige Dateien angelegt, auf die wir im nächsten Kapitel noch detaillierter eingehen werden. Bevor wir weitermachen, starten wir nun den Test-Server mit dem Programm ``manage.py`` und prüfen, ob unser Projekt ordungsgemäß läuft. .. admonition:: manage.py ``manage.py`` ist ein kleines Helfertool, welches beim Initialisieren des Projekts automatisch mit angelegt wurde. Damit könnt ihr verschiedene administrative Aufgaben in eurem Projekt erledigen, wie zum Beispiel dem Anlegen von neuen Apps oder dem Starten des Testservers. Wir werden es im Kurs immer wieder nutzen und die einzelnen Kommandos erklären. Mehr Infos zu manage.py und django-admin findet ihr auch hier: ``_ den Test-Server starten ========================== Um zu Prüfen, ob alles geklappt hat, starten wir nun den **Test-Server** und rufen die Test-Webseite im Browser auf. Dazu nutzen wir das Programm ``manage.py``. .. code-block:: shell (eventenv) python manage.py runserver Die Ausgabe auf der Konsole sollte so oder so ähnlich aussehen: .. code-block:: shell Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. August 17, 2021 - 13:51:04 Django version stable.6, using settings 'event_manager.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. [17/Aug/2021 13:51:44] "GET / HTTP/1.1" 200 10697 [17/Aug/2021 13:51:44] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423 [17/Aug/2021 13:51:44] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184 [17/Aug/2021 13:51:44] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876 [17/Aug/2021 13:51:44] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692 Not Found: /favicon.ico [17/Aug/2021 13:51:44] "GET /favicon.ico HTTP/1.1" 40stable116 Diese Ausgaben sind erstmal nicht weiter wichtig. Wichtig ist nur, dass kein Fehler auftritt und der Server abbricht. Das ist an dieser Stelle aber fast ausgeschlossen, da wir ja noch nicht eine einzige Zeile Code geschrieben haben. **Vorsicht:** bitte nicht vorgreifen und an diese Stelle ``python manage.py migrate`` ausführen, wie das in der Ausgabe vorgeschlagen wird. Wir müssen noch Änderungen am Code vornehmen und das User-Modell anpassen, bevor wir die Datenbank migrieren. Unter der angegebenen URL kann man das Django-Projekt jetzt im Browser aufrufen: .. code-block:: shell http://127.0.0.1:8000 Wenn alles geklappt hat, sehen wir die Django-Testpage im Browser: .. image:: /images/Django_2.1_landing_page.png :alt: Django Webserver Test .. admonition:: der Django-Testserver mit dem Befehl ``python manage.py runserver`` wurde der Testserver gestartet. Das ist ein einfacher Webserver, der uns die Daten unkompliziert über ``HTTP`` ausliefert. Allerdings ist dieser Webserver nur für die Entwicklung gedacht. In einer **Produktiv-Umgebung darf dieser auf keinen Fall** verwendet werden, da er dafür nicht ausgelegt ist. Er wurde nicht mit den nötigen Performance- und Sicherheitsvorkehrungen gebaut, die nötig sind, um einen Produktivbetrieb zu gewährleisten. ``_ **Der Testserver muss nicht nach jeder Code-Änderung neu gestartet werden, das tut er dank StatReloader selbständig**. Falls er mal hängen bleibt (was unter Windows häufig vorzukommen scheint), muss man ihn neu starten. Der Testserver lässt sich mit ``CTRL + C`` stoppen.