Настройка URL-маршрутизации и работа с шаблонами
Вы уже знаете, что Django использует архитектуру MTV (Model-Template-View). Модели работают с базой данных, а представления (Views) обрабатывают запросы. Но как Django понимает, какое представление вызвать по определённому адресу? За это отвечает URL-маршрутизация. А после обработки запроса представление должно что-то показать пользователю — здесь на помощь приходят шаблоны.
URL-маршрутизация: Путь к вашим представлениям
URL-маршрутизация в Django связывает URL-адреса, которые пользователь вводит в браузере, с нужными функциями-представлениями в вашем приложении.
Представьте, что ваш сайт — это большой дом, а URL-адреса — это адреса комнат. Система маршрутизации — это привратник, который, получив адрес комнаты, указывает, куда идти.
Как это работает?
В Django маршруты определяют в файлах urls.py. Обычно есть главный urls.py в корне проекта и отдельные urls.py в каждом приложении.
- Главный
urls.pyпроекта: Это точка входа. Здесь вы "подключаете" маршруты из ваших приложений. urls.pyприложения: В каждом приложении вы определяете конкретные маршруты для его функционала.
Давайте посмотрим на пример.
# project_name/urls.py (главный файл проекта)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # Подключаем URL-ы из приложения 'blog'
path('', include('main_app.urls')), # Подключаем URL-ы из приложения 'main_app' для корневого адреса
]
Здесь include('blog.urls') говорит Django: "Если URL начинается с blog/, ищи дальнейшие маршруты в файле blog/urls.py".
Теперь создадим blog/urls.py:
# blog/urls.py (файл URL-ов приложения 'blog')
from django.urls import path
from . import views # Импортируем представления из текущего приложения
urlpatterns = [
path('', views.post_list, name='post_list'), # blog/
path('<int:post_id>/', views.post_detail, name='post_detail'), # blog/1/, blog/25/
path('about/', views.about_page, name='about'), # blog/about/
]
Важно: Параметр
name='...'очень полезен. Он позволяет ссылаться на URL по имени, а не по жёстко заданному пути. Это делает код гибким: если вы измените URL-путь, вам не придётся менять все ссылки на него в коде, достаточно будет изменить его только вurls.py.
Типы путей в path()
- Статические пути:
path('about/', views.about_page)— для фиксированных URL. - Динамические пути (конвертеры):
path('<int:post_id>/', views.post_detail)— позволяют захватывать части URL как переменные.<int:post_id>: захватывает целое число и передаёт его как аргументpost_idв функциюpost_detail.- Другие конвертеры:
str(любая строка, кроме/),slug(строка из букв, цифр, дефисов и подчёркиваний),uuid(уникальный идентификатор),path(любая строка, включая/).
Шаблоны Django: Динамическое отображение данных
После того как представление обработало запрос и подготовило данные, их нужно красиво отобразить пользователю. Для этого в Django используют шаблоны. Шаблоны — это HTML-файлы с особыми метками, которые Django заменяет реальными данными.
Основные концепции шаблонов
-
Переменные: Позволяют выводить данные из контекста, переданного из представления.
<h1>Привет, {{ user_name }}!</h1> <p>Сегодня: {{ current_date }}</p>Переменные заключаются в двойные фигурные скобки
{{ }}. -
Теги: Выполняют логические операции, такие как циклы, условные операторы, включение других шаблонов.
{% if user.is_authenticated %} <p>Вы вошли как {{ user.username }}</p> {% else %} <p><a href="/login/">Войти</a></p> {% endif %} {% for item in items %} <li>{{ item.name }}</li> {% endfor %}Теги заключаются в
{% %}. -
Фильтры: Модифицируют вывод переменных.
<p>Цена: {{ price|floatformat:2 }} руб.</p> {# Форматирует число до двух знаков после запятой #} <p>Дата: {{ date|date:"d.m.Y" }}</p> {# Форматирует дату #}Фильтры применяются после переменной через вертикальную черту
|.
Создание и использование шаблонов
-
Настройка директорий шаблонов: В файле
settings.pyвашего проекта укажите, где Django будет искать шаблоны. Обычно это папкаtemplatesвнутри каждого приложения или общая папкаtemplatesв корне проекта.# settings.py TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], # Общая папка для шаблонов проекта 'APP_DIRS': True, # Искать шаблоны в папках 'templates' внутри каждого приложения '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', ], }, }, ] -
Создание шаблона: Внутри папки
templatesвашего приложения (например,blog/templates/blog/) создайте HTML-файл, напримерpost_list.html.<!-- blog/templates/blog/post_list.html --> <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Список постов</title> </head> <body> <h1>Все посты</h1> {% if posts %} <ul> {% for post in posts %} <li> <h2><a href="{% url 'post_detail' post.id %}">{{ post.title }}</a></h2> <p>{{ post.content|truncatechars:100 }}</p> </li> {% endfor %} </ul> {% else %} <p>Постов пока нет.</p> {% endif %} </body> </html>Обратите внимание на
{% url 'post_detail' post.id %}. Это мощный тег, который генерирует URL по имени маршрута и переданным аргументам. -
Рендеринг шаблона в представлении: В функции представления используйте функцию
render()для объединения шаблона с данными.# blog/views.py from django.shortcuts import render from .models import Post # Предположим, у нас есть модель Post def post_list(request): posts = Post.objects.all().order_by('-pub_date') # Получаем все посты context = {'posts': posts} # Создаем словарь с данными для шаблона return render(request, 'blog/post_list.html', context) def post_detail(request, post_id): post = Post.objects.get(id=post_id) # Получаем конкретный пост context = {'post': post} return render(request, 'blog/post_detail.html', context)Функция
render()принимает объектrequest, путь к шаблону и словарьcontext, который содержит данные, доступные в шаблоне.
Наследование шаблонов: DRY в действии
Принцип DRY (Don't Repeat Yourself — не повторяйся) очень важен в разработке. В веб-приложениях часто есть общие элементы: шапка сайта, подвал, навигация. Вместо того чтобы копировать их в каждый HTML-файл, Django предлагает наследование шаблонов.
Вы создаёте базовый шаблон (base.html) с общими элементами и "блоками", которые дочерние шаблоны могут переопределять.
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>{% block title %}Мой сайт{% endblock %}</title>
</head>
<body>
<header>
<h1>Мой крутой блог на Django</h1>
<nav>
<ul>
<li><a href="{% url 'post_list' %}">Посты</a></li>
<li><a href="{% url 'about' %}">О нас</a></li>
</ul>
</nav>
</header>
<main>
{% block content %}
<!-- Здесь будет основной контент дочерних шаблонов -->
{% endblock %}
</main>
<footer>
<p>© 2025 Мой блог. Все права защищены.</p>
</footer>
</body>
</html>
А дочерний шаблон будет выглядеть так:
<!-- blog/templates/blog/post_list.html -->
{% extends 'base.html' %} {# Указываем, от какого шаблона наследуемся #}
{% block title %}Список постов - {{ block.super }}{% endblock %} {# Переопределяем заголовок #}
{% block content %} {# Переопределяем блок контента #}
<h1>Все посты</h1>
{% if posts %}
<ul>
{% for post in posts %}
<li>
<h2><a href="{% url 'post_detail' post.id %}">{{ post.title }}</a></h2>
<p>{{ post.content|truncatechars:100 }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>Постов пока нет.</p>
{% endif %}
{% endblock %}
{% extends 'base.html' %} указывает, что этот шаблон наследуется от base.html.
{% block title %} и {% endblock %} определяют блоки, которые могут быть переопределены.
{{ block.super }} внутри блока позволяет сохранить содержимое родительского блока и добавить к нему что-то новое.
Теперь вы понимаете, как запросы пользователей попадают в нужные части вашего приложения Django и как эти части формируют динамические веб-страницы. Это основа для создания интерактивных и функциональных веб-приложений.
В следующем разделе мы углубимся в работу с админ-панелью Django, которая позволит вам управлять данными вашего приложения без написания дополнительного кода, и научимся создавать и обрабатывать веб-формы для взаимодействия с пользователем.