URL-Routing und Artikeldetailseiten
In diesem Kapitel lernst du die dynamische Routing-Konfiguration von Django kennen, um Artikeldetailseiten und die Link-Navigation zwischen Seiten zu implementieren.
Was ist dynamisches Routing?
Die Startseite zeigt alle Artikel an, und jeder Artikel benötigt eine eigene unabhängige Detailseite.
Die URL sollte so aussehen:/post/1/、/post/2/, wobei der numerische Teil der Primärschlüssel (pk) des Artikels ist.
Dynamisches RoutingErmöglicht URLs, Variablen zu enthalten, und Django extrahiert sie automatisch und übergibt sie an die View-Funktion.
Dynamisches Routing konfigurieren
Beispiel
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
# int:pk — Integer-Parameter in der URL, benannt pk (Primärschlüssel)
# name='post_detail' — Route benennen, in Templates mit {% url %} referenziert
path('post/<int:pk>/', views.post_detail, name='post_detail'),
]
Erklärung des Route-Konverters:
| Konverter | Beispielpfad | Übereinstimmungsregeln |
|---|---|---|
<int:pk> | /post/3/ | Entspricht positiver Ganzzahl |
<str:slug> | /post/django-guide/ | Entspricht einer Zeichenkette (ohne /) |
<slug:slug> | /post/django-guide/ | Entspricht Buchstaben, Zahlen, -, _ |
<uuid:id> | /post/uuid/ | Entspricht UUID-Format |
Die Detailseiten-View schreiben
Die Detailseite muss den entsprechenden Artikel anhand der pk in der URL aus der Datenbank abfragen.
Beispiel
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_detail(request, pk):
"""Artikeldetailseite"""
# get_object_or_404: einen einzelnen Datensatz abfragen
# Das Objekt zurückgeben, wenn gefunden; andernfalls automatisch die 404-Seite zurückgeben (ohne try/except zu schreiben)
post = get_object_or_404(Post, pk=pk)
context = {
'post': post,
'title': f{post.title} - EXAMPLE Blog
}
return render(request, 'blog/post_detail.html', context)
get_object_or_404ist Djangos Best Practice. Es entsprichtPost.objects.get(pk=pk)+try/except Post.DoesNotExist, aber der Code ist prägnanter. Wenn Benutzer auf eine nicht existierende Artikel-ID zugreifen, sehen sie eine freundliche 404-Seite statt eines Fehlers.
Detailseiten-Template erstellen
Beispiel
{% extends 'blog/base.html' %}
{% block title %}{{ post.title }} - BEISPIEL Blog{% endblock %}
{% block content %}
<article class="post-view">
<span class="category-tag">{{ post.category.name }}</span>
<h1>{{ post.title }}</h1>
<time>{{ post.created_at|date:"Y-m-d" }}</time>
<!-- Der Body verwendet den |safe-Filter, um HTML zu rendern (HTML-Inhalt, der im Admin eingegeben wurde) -->
<div class="content">
{{ post.content|safe }}
</div>
<a href="{% url 'index' %}" class="back-link">← Zurück zur Startseite</a>
</article>
{% endblock %}
Detailseiten-Stil
Beispiel
.post-view {
max-width: 720px;
margin: 0 auto;
}
.category-tag {
display: inline-block;
padding: 4px 12px;
background: #E8EEF5;
color: #3D71A6;
border-radius: 12px;
font-size: 13px;
margin-bottom: 12px;
}
.post-view h1 {
font-size: 32px;
margin-bottom: 12px;
line-height: 1.4;
}
.post-view time {
display: block;
color: #999;
font-size: 14px;
margin-bottom: 30px;
}
.content {
line-height: 1.8;
font-size: 16px;
color: #333;
}
.content h2 {
margin: 24px 0 12px;
font-size: 22px;
}
.content p {
margin-bottom: 12px;
}
.back-link {
display: inline-block;
margin-top: 40px;
color: #2c3e50;
text-decoration: none;
}
|safeDer Filter teilt Django mit: Dieser Inhalt ist sicheres HTML, rendere ihn direkt, escape ihn nicht. Wenn du safe verwendest, stelle sicher, dass der Inhalt vertrauenswürdig ist (z. B. Inhalte, die du selbst im Admin bearbeitet hast). Wenn es sich um von Benutzern eingereichten Inhalt handelt, füge niemals safe hinzu, sonst besteht ein XSS-Risiko.
Links in Templates generieren: {% url %}
Füge den Artikelkarten auf der Startseite Links zur Detailseite hinzu.
Beispiel
<div class="article-grid">
{% for post in posts %}
<a href="{% url 'post_detail' post.pk %}" class="card-link">
<div class="article-card">
<div class="card-content">
<span class="card-category">{{ post.category.name }}</span>
<h3>{{ post.title }}</h3>
<p>{{ post.summary|truncatechars:80 }}</p>
<span class="card-date">{{ post.created_at|date:"Y-m-d" }}</span>
</div>
</div>
</a>
{% endfor %}
</div>
{% url 'post_detail' post.pk %}Es generiert automatisch die korrekte URL basierend auf dem Routennamen und den Parametern.
Wenn sich die Route später ändert (z. B.,/post/Wechsel zu/article/), werden die Links im Template automatisch aktualisiert, ohne manuelle Änderung.
Füge get_absolute_url() zum Modell hinzu
Das Definieren dieser Methode im Post-Modell ermöglicht es dem Admin-Backend, den in Django integrierten Tools usw., den Link zur Detailseite automatisch zu finden.
Beispiel
from django.urls import reverse
class Post(models.Model):
# ... Felddefinitionen ...
def __str__(self):
return self.title
def get_absolute_url(self):
# reverse: URL anhand von Routennamen und Parametern nachschlagen
return reverse('post_detail', kwargs={'pk': self.pk})
Kapitelzusammenfassung
In diesem Kapitel hast du den Kern des Django-Routings gemeistert: dynamisches Routing.<int:pk>Parameterübergabe, sichere Abfrage mit get_object_or_404, {% url %}-Template-Tag zum Generieren von Links, Reverse-URL-Lookup.
Jetzt hat der Blog zwei Seiten: die Startseitenliste und die Artikeldetailseite. Ein Klick auf eine Karte navigiert zum Lesen des vollständigen Artikels.
Weitere Erweiterungen