W3docs

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

EbeneDjango-BegriffVerantwortung
DatenModelPython-Klasse, die einer Datenbanktabelle entspricht
PräsentationTemplateHTML-Datei mit {{ variable }}-Platzhaltern
LogikViewPython-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           # Windows

Nach 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 --version

Django 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 mysite

Dabei 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 point

manage.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 blog

Registrieren 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 functions

Models 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 first

Verwendete Feldtypen:

FeldZweck
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 migrate

Sie 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... OK

Fü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 createsuperuser

Django 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 runserver

Melden 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.html

blog/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 / FilterFunktion
{% 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:30Text 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:

  1. Browser sendet GET /
  2. Djangos URL-Dispatcher passt '' an und ruft post_list auf
  3. post_list fragt Post.objects.all() ab (übersetzt in SELECT * FROM blog_post ORDER BY date_posted DESC)
  4. Django rendert post_list.html und fügt die Beiträge in das Template ein
  5. 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.py

Hä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

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.

Was this page helpful?