Django Tutorial
Django von Grund auf lernen: Framework installieren, Models, Views und Templates erstellen, Migrationen ausführen und eine Web-App starten.
Django ist ein hochentwickeltes Python-Web-Framework, mit dem sich sichere und skalierbare Webanwendungen schnell erstellen lassen. Es folgt dem Model-Template-View (MTV)-Architekturmuster — einem engen Verwandten von MVC — und bringt ein ORM, ein Admin-Interface, URL-Routing, Authentifizierung und vieles mehr bereits mit. Djangos „Batteries-Included"-Philosophie bedeutet, dass Sie Ihre Zeit auf die Anwendungslogik verwenden, anstatt Infrastruktur zusammenzubauen.
Dieses Tutorial führt durch die wesentlichen Schritte: Django in einer virtuellen Umgebung installieren, ein Projekt und eine App erstellen, Models definieren, Views schreiben, Templates bauen, Datenbankmigrationen ausführen und alles im Browser überprüfen.
Warum Django verwenden
Batteries Included
Django liefert ein integriertes Admin-Panel, Benutzerauthentifizierung, Formularverarbeitung, ein ORM, Caching-Unterstützung und Internationalisierungstools mit. Es ist nicht nötig, nach Drittanbieter-Paketen zu suchen, um diese Grundfunktionen abzudecken.
Sicherheit standardmäßig
Django schützt vor SQL-Injection, indem es parametrisierte Abfragen über sein ORM verwendet. Es bietet zudem integrierten Schutz gegen Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF) und Clickjacking. Der geheime Schlüssel, der DEBUG-Modus und die ALLOWED_HOSTS-Einstellungen reduzieren die Angriffsfläche zusätzlich.
Skalierbarkeit
Django betreibt stark frequentierte Seiten wie Instagram und Disqus. Sein Caching-Framework lässt sich mit Memcached und Redis integrieren, und das ORM unterstützt Datenbankverbindungspools. Sie können vertikal oder horizontal skalieren, ohne den Anwendungscode zu ändern.
Großes Ökosystem
Djangos Paketverzeichnis listet Tausende von Drittanbieter-Apps — REST APIs (djangorestframework), Bildverarbeitung, Zahlungsgateways und mehr. Die Stabilität des Frameworks und der lange Release-Zyklus bedeuten, dass diese Pakete aktiv gepflegt werden.
Wie Djangos MTV-Muster funktioniert
| Ebene | Django-Begriff | Verantwortung |
|---|---|---|
| Daten | Model | Python-Klasse, die einer Datenbanktabelle entspricht |
| Präsentation | Template | HTML-Datei mit {{ variable }}-Platzhaltern |
| Logik | View | Python-Funktion (oder -Klasse), die Daten liest und eine Antwort zurückgibt |
Der URL-Dispatcher (urls.py) ordnet eingehende Anfragepfade dem richtigen View zu. Der View fragt Models ab und übergibt dann Daten an ein Template. Das gerenderte HTML wird an den Browser zurückgegeben.
Eine virtuelle Umgebung einrichten
Isolieren Sie Django-Projekte immer in einer virtuellen Umgebung, damit Abhängigkeiten nicht zwischen Projekten in Konflikt geraten.
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
venv\Scripts\activate # WindowsNach der Aktivierung zeigt Ihre Eingabeaufforderung (venv). Jedes pip install ab diesem Punkt betrifft nur diese Umgebung.
Django installieren
Installieren Sie Django mit aktivierter virtueller Umgebung über pip:
pip install djangoÜberprüfen Sie die Installation:
python -m django --versionDjango gibt eine Versionszeichenfolge wie 5.1.4 aus.
Ein Django-Projekt erstellen
Ein Projekt ist der übergeordnete Container für Ihre gesamte Website. Erstellen Sie eines mit:
django-admin startproject mysite
cd mysiteDabei entsteht die folgende Struktur:
mysite/
├── manage.py # Command-line utility for this project
└── mysite/
├── __init__.py
├── settings.py # Project configuration (database, installed apps, …)
├── urls.py # Root URL dispatcher
├── asgi.py # ASGI entry point
└── wsgi.py # WSGI entry pointmanage.py ist Ihr Hauptwerkzeug zum Ausführen von Befehlen wie dem Starten des Entwicklungsservers, dem Erstellen von Migrationen und dem Anlegen eines Superusers. Der innere mysite/-Ordner ist das Python-Paket für das Projekt selbst.
Eine Django-App erstellen
Ein Projekt kann mehrere Apps enthalten — eigenständige Module, die jeweils für einen Funktionsbereich zuständig sind. Erstellen Sie eine Blog-App:
python manage.py startapp blogRegistrieren Sie sie, damit Django ihre Models, Templates und statischen Dateien finden kann. Öffnen Sie mysite/settings.py und fügen Sie 'blog' zu INSTALLED_APPS hinzu:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # <-- add this line
]Das App-Verzeichnis sieht nach der Erstellung wie folgt aus:
blog/
├── __init__.py
├── admin.py # Register models with the admin interface
├── apps.py # App configuration
├── migrations/ # Auto-generated migration files
│ └── __init__.py
├── models.py # Database models
├── tests.py
└── views.py # View functionsModels definieren
Ein Model ist eine Python-Klasse, die django.db.models.Model als Unterklasse hat. Jedes Klassenattribut entspricht einer Datenbankspalte. Djangos ORM übersetzt Ihren Python-Code in SQL und kümmert sich um alle Datenbankinteraktionen.
Öffnen Sie blog/models.py und definieren Sie ein Post-Model:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-date_posted'] # Newest posts firstVerwendete Feldtypen:
| Feld | Zweck |
|---|---|
CharField(max_length=N) | Kurzer Text mit einer maximalen Länge |
TextField() | Text unbegrenzter Länge |
ForeignKey(…, on_delete=CASCADE) | Viele-zu-eins-Beziehung; löscht Beiträge, wenn ihr Autor gelöscht wird |
DateTimeField(auto_now_add=True) | Wird einmalig beim Erstellen des Datensatzes gesetzt |
DateTimeField(auto_now=True) | Wird jedes Mal aktualisiert, wenn der Datensatz gespeichert wird |
Die __str__-Methode steuert, wie das Objekt im Admin-Panel und in der Python-Shell angezeigt wird.
Migrationen ausführen
Nach dem Definieren oder Ändern von Models müssen Migrationen erstellt und angewendet werden — versionskontrollierte Anweisungen, die das Datenbankschema aktualisieren.
# Generate a new migration file from your model changes
python manage.py makemigrations
# Apply all pending migrations to the database
python manage.py migrateSie sehen eine Ausgabe wie:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OKFühren Sie migrate immer dann aus, wenn Sie Modell-Felder hinzufügen, entfernen oder ändern. Bearbeiten Sie Migrationsdateien niemals manuell, es sei denn, Sie verstehen deren SQL vollständig.
Das Django Admin Panel verwenden
Das eingebaute Admin-Interface ermöglicht es Ihnen, Datensätze über einen Browser zu erstellen, zu lesen, zu aktualisieren und zu löschen — ohne benutzerdefinierte Benutzeroberfläche. Registrieren Sie das Post-Model in blog/admin.py:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date_posted')
list_filter = ('date_posted', 'author')
search_fields = ('title', 'content')Erstellen Sie ein Superuser-Konto, mit dem Sie sich anmelden können:
python manage.py createsuperuserDjango fordert einen Benutzernamen, eine E-Mail-Adresse und ein Passwort an. Starten Sie dann den Entwicklungsserver und öffnen Sie http://127.0.0.1:8000/admin/:
python manage.py runserverMelden Sie sich mit den Superuser-Anmeldedaten an und Sie sehen das Posts-Model unter dem Abschnitt „Blog".
Views schreiben
Ein View ist eine Python-Funktion (oder -Klasse), die eine HTTP-Anfrage empfängt und eine HTTP-Antwort zurückgibt. Öffnen Sie blog/views.py:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
"""Display all published posts, newest first."""
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
"""Display a single post by primary key."""
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})get_object_or_404 ist eine hilfreiche Abkürzung: Sie holt das Objekt aus der Datenbank oder gibt automatisch eine 404-Antwort zurück, falls es nicht existiert. Das dritte Argument für render ist ein Kontext-Dictionary — seine Schlüssel werden zu Template-Variablen.
Templates erstellen
Templates sind HTML-Dateien, die Django Template Language (DTL)-Tags enthalten. Erstellen Sie die Verzeichnisstruktur:
blog/
└── templates/
└── blog/
├── base.html
├── post_list.html
└── post_detail.htmlblog/templates/blog/base.html — ein gemeinsames Layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
<header><h1>My Blog</h1></header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
blog/templates/blog/post_list.html — die Listenseite:
{% extends "blog/base.html" %}
{% block title %}All Posts{% endblock %}
{% block content %}
{% for post in posts %}
<article>
<h2><a href="/blog/{{ post.pk }}/">{{ post.title }}</a></h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
{% empty %}
<p>No posts yet.</p>
{% endfor %}
{% endblock %}
blog/templates/blog/post_detail.html — die Detailseite:
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h2>{{ post.title }}</h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<div>{{ post.content }}</div>
<a href="/">Back to all posts</a>
{% endblock %}
Verwendete DTL-Funktionen:
| Tag / Filter | Funktion |
|---|---|
{% extends "…" %} | Von einem Basis-Template erben |
{% block name %} | Einen ersetzbaren Abschnitt definieren |
{{ variable }} | Einen Wert ausgeben (automatisch HTML-escaped) |
{% for … %} / {% empty %} | Schleife mit Fallback für leere Listen |
|date:"N j, Y" | Einen Datums-/Uhrzeitwert formatieren |
|truncatewords:30 | Text auf 30 Wörter kürzen |
URLs konfigurieren
Die URL-Konfiguration ordnet Anfragepfade View-Funktionen zu.
blog/urls.py — erstellen Sie diese Datei im blog-Verzeichnis:
from django.urls import path
from . import views
app_name = 'blog' # Enables namespaced URL reversing
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]mysite/urls.py — binden Sie die App-URLs in das Projektstamm-URL ein:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
path('', include('blog.urls', namespace='blog_root')),
]Der <int:pk>-Pfadkonverter erfasst eine Ganzzahl aus der URL und übergibt sie als pk-Schlüsselwortargument an post_detail.
Den vollständigen Ablauf überprüfen
Starten Sie den Entwicklungsserver:
python manage.py runserverÖffnen Sie dann http://127.0.0.1:8000/ in Ihrem Browser. Wenn noch keine Beiträge vorhanden sind, zeigt das Template „No posts yet." an. Melden Sie sich bei http://127.0.0.1:8000/admin/ an und fügen Sie einen Beitrag hinzu. Aktualisieren Sie die Startseite — der Beitrag erscheint sofort.
Der Anfragedurchlauf für die Startseite ist:
- Browser sendet
GET / - Djangos URL-Dispatcher passt
''an und ruftpost_listauf post_listfragtPost.objects.all()ab (übersetzt inSELECT * FROM blog_post ORDER BY date_posted DESC)- Django rendert
post_list.htmlund fügt die Beiträge in das Template ein - Das gerenderte HTML wird an den Browser zurückgegeben
Django ORM Query-Spickzettel
Das ORM ermöglicht es Ihnen, SQL-Abfragen mithilfe von Python-Methodenketten zu erstellen. Die häufigsten Lookups zu kennen spart erheblich Zeit:
# All posts
Post.objects.all()
# Posts by a specific author
Post.objects.filter(author__username='alice')
# Posts containing a word in the title (case-insensitive)
Post.objects.filter(title__icontains='django')
# The five most recent posts
Post.objects.order_by('-date_posted')[:5]
# Count posts
Post.objects.count()
# Get one object (raises DoesNotExist if not found)
Post.objects.get(pk=1)
# Exclude posts by a specific author
Post.objects.exclude(author__username='alice')Jede dieser Anweisungen generiert eine SQL-Abfrage erst dann, wenn das Queryset ausgewertet wird (iteriert, geslict oder in eine Liste umgewandelt). Dies wird als Lazy Evaluation bezeichnet und hält unnötige Datenbankaufrufe auf ein Minimum.
Zusammenfassung der Projektstruktur
Nach Abschluss dieses Tutorials sieht die Projektstruktur wie folgt aus:
mysite/
├── manage.py
├── mysite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── blog/
├── admin.py
├── migrations/
│ └── 0001_initial.py
├── models.py
├── templates/
│ └── blog/
│ ├── base.html
│ ├── post_list.html
│ └── post_detail.html
├── urls.py
└── views.pyHäufige Fallstricke
Die App vergessen zu registrieren. Wenn 'blog' in INSTALLED_APPS fehlt, findet Django seine Models oder Templates nicht, und makemigrations erzeugt keine Ausgabe für diese App.
migrate nach makemigrations überspringen. Nur makemigrations auszuführen erstellt die Migrationsdatei, berührt aber nicht die Datenbank. Folgen Sie immer mit migrate nach.
Fehler „Template not found". Django sucht Templates im templates/-Verzeichnis jeder App. Der zusätzliche blog/-Unterordner innerhalb von templates/ (templates/blog/post_list.html) ist eine Konvention, die Namenskollisionen zwischen Apps verhindert — lassen Sie ihn nicht weg.
DEBUG = True in der Produktion. Der Entwicklungsserver und DEBUG = True legen Tracebacks für alle offen. Setzen Sie DEBUG = False und konfigurieren Sie ALLOWED_HOSTS, bevor Sie deployen.
Nächste Schritte
- Python-Module — verstehen Sie, wie Pythons Modulsystem Djangos Import-Struktur zugrunde liegt.
- Python PIP — verwalten Sie Django und seine Abhängigkeiten.
- Python Virtuelle Umgebungen — halten Sie jedes Django-Projekt isoliert.
- MySQL mit Python — tauschen Sie SQLite gegen eine produktionstaugliche Datenbank aus.
- MongoDB mit Python — verwenden Sie ein NoSQL-Backend mit Django.
Djangos offizielle Dokumentation auf docs.djangoproject.com behandelt klassenbasierte Views, Formulare, Authentifizierung, REST APIs mit Django REST Framework und die Bereitstellung in der Produktion — alles natürliche nächste Schritte, sobald Sie mit den hier behandelten Grundlagen vertraut sind.