Untersuchen der Installation
Betrachten wir nun die bisherigen Verzeichnisse unseres Django-Projekts:
event_manager
├── manage.py
├── db.sqlite3
└── event_manager
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
├── requirements.txt
├── requirements-dev.txt
├── requirements.in
├── requirements-dev.in
.gitigore
...
das äußere event_manager/
Das äußere event_manager
ist der Container für das gesamte Django-Projekt. Ein Django-Projekt besteht aus einer oder meist mehreren Apps, zum Beispiel einer Blog-App oder einem Webshop. Apps können völlig unabhängig sein oder von anderen Apps abhängen und mit ihnen kommunizieren.
Wir finden hier noch zwei weitere wichtige Dinge: das Programm manage.py
und das Verzeichnis event_manager/
.
manage.py
Ein kleines Helfertool, mit dem auf verschiedeneste Weise mit dem aktuellen Django-Projekt interagiert werden kann. Wir können damit die Verzeichnis-Struktur für Apps anlegen, Datenbanken migrieren, Daten im- und exportieren, Tests starten und vieles mehr.
Manage.py
ist im Grunde das gleiche Programm wie django-admin
, mit der Ausnahme, dass in manage.py
die projektspezifischen Settings berücksichtigt werden. Django-Admin hingegen kennt diese Settings nicht. Deshalb ist manage.py
für projektbezogene Arbeiten zu bevorzugen.
weiterführender Link:
db.sqlite3
Die Default-Datenbank für das aktuelle Django-Projekt ist SQLite. Es handelt sich dabei um ein einfaches, aber dennoch mächtige relationales Datenbanksystem, das gerne im Entwicklungsprozess von Django-Applikationen eingesetzt wird. In Produktivumgebungen sollte sie allerdings nicht genutzt werden, da sie unter anderem schlecht skaliert und nicht so richtig multiuserfähig ist.
mehr dazu: https://stackoverflow.com/questions/6913833/using-sqlite-in-django-in-production
Das vorliegende Buch wird sqlite
als Datenbank nutzen. Professionelle Projekte nutzen -wie in der Pythonwelt üblich- häufig Postgres
.
das innere event_manager
Im inneren event_manager
-Verzeichnis finden wir folgende Dateien vor:
__init__.py
Eine leere Datei, die Python mitteilt, dass dieses Verzeichnis als Python-Paket betrachtet werden soll. Wir werden diese Datei nicht weiter beachten in diesem Buch.
asgi.py
Der Einstiegspunkt für ASGI-kompatible Webserver für das Projekt. Asgi steht für asynchronous Gateway Interface und wird zum Beispiel für Chat-Programme oder Multiplayer-Games genutzt. In diesem Buch nutzen wir ASGI nicht.
wsgi.py
Der Einstiegspunkt für WSGI-kompatible Webserver für das Projekt. WSGI steht für Web Server Gateway Interface. Das Web Server Gateway Interface (WSGI) ist eine Schnittstellen-Spezifikation für die Programmiersprache Python, die eine Schnittstelle zwischen Webservern und Webframeworks bzw. Web Application Servern festlegt, um die Portabilität von Webanwendungen auf unterschiedlichen Webservern zu fördern. Ein Gunicorn Webserver beispielsweise für diese Datei als Einstiegspunkt nehmen:
gunicorn --bind 0.0.0.0:8000 event_manager.wsgi
Weiterführender Link:
settings.py
Das sind die Projekteinstellungen. Hier werden die meisten Konfigurationselemente festgelegt, z. B. ob sich das Projekt im DEBUG-Modus befindet oder welche Datenbank genutzt wird. Die settings.py ist also die Haupt-Konfiguration. In der event_manager/event_manager/settings.py
nehmen wir nun folgende Anpassungen vor:
Anpassen der Settings
Wir legen erstmal einen SECRET_KEY
fest und definieren den erlaubten
Host:
SECRET_KEY = "Ultralong42geheimer"
ALLOWED_HOSTS = ["127.0.0.1"]
Der SECRET_KEY
dient Django als Basis für das Erstellen von kryptographischen
Hash-Werten und wird zum Beispiel genutzt, um Passwort-Token oder CSRF-Token zu
erstellen. Er muss auf alle Fälle geheim bleiben. Wir werden ihn später noch auslagern
und anpassen.
ALLOWED_HOSTS
In dieser Liste werden die erlaubten Hosts eingetragen, um den vom User
mitgesendeten Host-Header zu validieren. D.h. wenn die Seite später über
infos.example.com
ausgeliefert werden soll, trägt man die Domain hier genauso
ein.
Wenn der Host-Header nicht validiert wird, kann ein Angreifer einen
gefälschten Header-Wert senden,
der für Cross-Site Request Forgery
, Cache-Poisoning
und dem
Fälschen von Links in E-Mails
verwendet werden kann.
Mehr zum Thema: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html
Wir passen den DIRS
-Key in den TEMPLATES
an und setzen APP_DIRS
auf True
. Damit sagen wir Django, dass auch in den Apps nach Template-Dateien gesucht werden soll (später mehr zu Templates und Apps).
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "event_manager" / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
und verändern die Zeitzone und Einstellungen zur Internationalisierung.
LANGUAGE_CODE = "de"
TIME_ZONE = "Europe/Berlin"
USE_I18N = True
USE_L10N = True
USE_TZ = True
|
Default-Sprache der Website |
|
Zeitzone der Website |
|
ermöglicht den Umgang mit mehreren Sprachen |
|
ermöglicht die Lokalisierung (Format Von Zeit und Zahlen) |
|
speichert ein Datetime-Object immer in UTC |
|
Generierung von Hash-Schlüsseln |
|
Liste der erlaubten Hosts |
urls.py
urls.py
ist, wie der Name schon sagt, der Ort, an dem die URLs für das Projekt festgelegt werden.
Obwohl wir nicht jede URL für das Projekt explizit in diese Datei
schreiben werden, müssen wir in dieser Datei auf alle anderen Stellen
hinweisen, an denen URLs deklariert wurden. URLs, die hier nicht gefunden
werden, exisitieren für Django nicht.
Eine Beispiel-Url für das Abrufen aller im System befindlichen Events könnte
zum Beispiel so aussehen: http://127.0.0.1:8000/events/show
URL Dispatcher
Gucken wir uns die event_manager/event_manager/urls.py
mal genauer an. Wir finden dort -von Django vorgeneriert- unter anderem diesen Eintrag:
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns
ist eine Liste, die unsere URLs verwaltet und mit den entsprechenden Applikationen verknüpft. Jeder Eintrag entspricht einer konkreten Route, die wir via URL ansprechen können. Bisher haben wir noch keine Apps, deshalb ist die Liste bis auf einen Eintrag auch leer (das ist dir URL zu der Django-Administrationsoberfläche, die wir uns aber erst später ansehen werden).
To design URLs for an app, you create a Python module informally called a URLconf (URL configuration). This module is pure Python code and is a mapping between URL path expressions to Python functions (your views).
This mapping can be as short or as long as needed. It can reference other mappings. And, because it’s pure Python code, it can be constructed dynamically.
—Django Documentation, URL dispatcher
In unseren Url-Definitionen innerhalb der urlpatterns
interessiert uns der
Domainname übrigens nicht (in diesem Fall http://127.0.0.1). Auch der Port
8000
ist für uns uninteressant. Wo unser Projekt später liegt, dh. über
welche Domain oder welchen Port es angesprochen wird, ist für uns also
vollkommen uninteressant. Im Gegenteil, wir wollen sogar vermeiden, dass unser
Projekt in irgendeiner Form an eine Domain gebunden ist, um das Projekt
möglichst portierbar zu halten.
Was uns allerdings interessiert, ist der sogenannte URL-Pfad.
Für uns also ist nur der Teil events/show
der URL http://example.com/events/show
interessant.
Im Laufe eines Projekts wird die urlpatterns
-Liste immer weiter anwachsen, da immer mehr Routen und damit URLs hinzukommen werden. Es bietet sich an, hier von Anfang an penibel auf Ordnung zu achten.
URL Design
Jedes moderne Web-Projekt sollte ein ordentliches URL-Design haben. Urls sollten sich auch nach einem Redesign/Neu-Entwicklung im Idealfall nicht ändern, da andere Resourcen womöglich auf das Projekt verlinken, und diese URLs dann nicht mehr stimmen würden. Freilich gibt es serverseitige Techniken, diese nicht-existenten URLs umzuschreiben.
eine gute URL zum Anlegen/Löschen eines Users schaut zum Beispiel so aus:
ein schlechtes Beispiel für die gleiche Aufgabe
Konsistenz
https://www.deepcrawl.com/blog/best-practice/guide-to-url-design/ https://www.w3.org/Provider/Style/URI
Mehr zum Thema URL-Resolving in der Django Doku: https://docs.djangoproject.com/en/stable/topics/http/urls/