Маршрутизация URL и страницы статей
В этой главе вы изучите конфигурацию динамической маршрутизации Django, чтобы реализовать страницы статей и навигацию по ссылкам между страницами.
Что такое динамическая маршрутизация?
На главной странице отображаются все статьи, и каждой статье нужна своя независимая страница статьи.
URL должен выглядеть так:/post/1/、/post/2/, где числовая часть — это первичный ключ статьи (pk).
Динамическая маршрутизацияПозволяет URL содержать переменные, а Django автоматически извлекает их и передаёт в функцию представления.
Настройка динамической маршрутизации
Пример
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
# int:pk — целочисленный параметр в URL с именем pk (первичный ключ)
# name='post_detail' — назовите маршрут, на который ссылаются в шаблонах с помощью {% url %}
path('post/<int:pk>/', views.post_detail, name='post_detail'),
]
Пояснение конвертеров маршрутов:
| Конвертер | Пример пути | Правила сопоставления |
|---|---|---|
<int:pk> | /post/3/ | Соответствует положительному целому числу |
<str:slug> | /post/django-guide/ | Соответствует строке (исключая /) |
<slug:slug> | /post/django-guide/ | Соответствует буквам, цифрам, -, _ |
<uuid:id> | /post/uuid/ | Соответствует формату UUID |
Напишите представление детальной страницы
Детальная страница должна запрашивать соответствующую статью из базы данных по pk в URL.
Пример
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_detail(request, pk):
"""Страница статьи"""
# get_object_or_404: запрос одной записи
# Возвращает объект, если он найден; иначе автоматически возвращает страницу 404 (без написания try/except)
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_404— лучшая практика Django. Это эквивалентноPost.objects.get(pk=pk)+try/except Post.DoesNotExist, но код более лаконичен. Когда пользователи обращаются к несуществующему ID статьи, они увидят понятную страницу 404 вместо ошибки.
Создайте шаблон страницы записи
Пример
{% extends 'blog/base.html' %}
{% block title %}{{ post.title }} - ПРИМЕР Блог{% 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>
<!-- В теле используется фильтр |safe для рендеринга HTML (HTML-содержимое, введённое в Admin) -->
<div class="content">
{{ post.content|safe }}
</div>
<a href="{% url 'index' %}" class="back-link">← На главную</a>
</article>
{% endblock %}
Стиль страницы записи
Пример
.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;
}
|safeФильтр сообщает Django: это содержимое — безопасный HTML, рендери его напрямую, не экранируй его. При использовании safe убедись, что содержимому можно доверять (например, контент, который вы сами отредактировали). Если это контент, отправленный пользователем, никогда не добавляй safe, иначе возникнет XSS.
Генерация ссылок в шаблонах: {% url %}
Добавьте ссылки на страницы с подробностями к карточкам статей на главной странице.
Пример
<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 %}Он автоматически сгенерирует правильный URL на основе имени маршрута и параметров.
Если маршрут позже изменится (например,/post/Изменить на/article/), ссылки в шаблоне будут автоматически обновляться без ручного изменения.
Добавьте get_absolute_url() в модель
Определение этого метода в модели Post позволяет административной панели, встроенным инструментам Django и т. д. автоматически находить ссылку на страницу с подробностями.
Пример
from django.urls import reverse
class Post(models.Model):
# ... определения полей ...
def __str__(self):
return self.title
def get_absolute_url(self):
# reverse: Поиск URL по имени маршрута и параметрам
return reverse('post_detail', kwargs={'pk': self.pk})
Итоги главы
В этой главе вы освоили основу маршрутизации Django: динамическую маршрутизацию.<int:pk>Передача параметров, безопасный запрос get_object_or_404, тег шаблона {% url %} для генерации ссылок, обратный поиск URL.
Теперь в блоге есть две страницы: список на главной странице и страница с подробностями статьи. Нажатие на карточку открывает полную статью.
Другие расширения