Краткое содержание предыдущих лекций
До этого момента вы познакомились с основами работы с представлениями (views) в Django. Мы обсудили, что такое представления, их роль в обработке HTTP-запросов и различия между функциональными (FBV) и классовыми представлениями (CBV). Вы научились создавать простые функции представлений, возвращать текстовые или HTML-ответы, а также обрабатывать ошибки с помощью HTTP-статус-кодов.
Мы плавно подошли к важной части работы любого веб-приложения — маршрутизации. До сегодняшнего дня вы узнали, что такое URLConf и как он помогает связывать запросы с подходящими обработчиками (представлениями). Теперь мы углубимся в процесс связывания URL-адресов с нашими представлениями.
Почему это важно?
Когда пользователь вашей веб-страницы нажимает на ссылку или вводит URL в браузере, Django должен понять, какое представление ему нужно вызывать, чтобы обработать запрос. Процесс маршрутизации помогает "перевести" URL в конкретную функцию или класс, который обработает запрос. Это как почтовая служба: URL — это адрес, а представление — это почтовый ящик, куда доставляют письмо (запрос).
Основы связывания URL с представлениями
В Django маршруты конфигурируются через файл urls.py. Существует главный файл маршрутов, обычно находящийся в корне проекта, и отдельные файлы urls.py в приложениях, которые добавляют свои маршруты. Наша задача — сопоставить каждый URL-адрес с определённым представлением.
Примерный процесс:
- Указываем шаблон URL.
- Привязываем шаблон к функции или классу представления.
- Определяем все маршруты в
urlpatterns.
Пример главного файла маршрутов project/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # Подключаем маршруты приложения "blog"
]
Пример файла маршрутов для приложения blog/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'), # Главная страница
path('about/', views.about, name='about'), # Страница "О нас"
]
Простой пример маршрута
Если вы хотите, чтобы URL /hello/ отображал сообщение "Привет, мир!", структура будет выглядеть так:
- Создаём представление.
- Указываем маршрут для URL.
Код в views.py:
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Привет, мир!")
Код в urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello_world, name='hello_world'),
]
Теперь, если вы откроете в браузере http://127.0.0.1:8000/hello/, вы увидите приветствие.
Использование функции path()
Основной синтаксис
Функция path() — это основной инструмент для маршрутизации запросов в Django. Её синтаксис:
path(route, view, kwargs=None, name=None)
route— строка, которая описывает шаблон URL.view— ссылка на функцию или класс представления.kwargs— дополнительные параметры, которые можно передать в представление (реже используется).name— имя маршрута. Оно позволяет ссылаться на маршрут через шаблоны или обратный вызов.
Пример:
path('home/', views.homepage, name='homepage')
Назначение имён маршрутам
Имена маршрутов — это мощный инструмент, позволяющий ссылаться на URL-ы в шаблонах и коде без жёсткого указания строк. Это удобно, потому что если вы измените URL, вам не придётся обновлять шаблоны или другие части кода.
Шаблонный пример в HTML:
<a href="{% url 'homepage' %}">Главная страница</a>
Если позже маршрут будет переписан на:
path('start/', views.homepage, name='homepage')
Ссылка в шаблоне автоматически обновится.
Примеры связанных маршрутов
Обработка запросов GET и POST
До этого мы использовали только метод GET, но Django позволяет обрабатывать и другие HTTP-методы, такие как POST. Вот пример:
Код в views.py:
from django.http import HttpResponse
def my_view(request):
if request.method == 'GET':
return HttpResponse("Это GET-запрос.")
elif request.method == 'POST':
return HttpResponse("Это POST-запрос.")
else:
return HttpResponse("Метод не поддерживается.")
Код в urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('example/', views.my_view, name='example'),
]
Теперь, если отправить запрос GET на /example/, вы получите "Это GET-запрос". Если отправить POST, результат изменится на "Это POST-запрос".
Динамические маршруты
Иногда нужно принимать параметры из URL и использовать их в представлениях. Например, если вы хотите отображать профиль пользователя по его ID.
Код маршрута с переменной:
path('profile/<int:user_id>/', views.user_profile, name='user_profile')
Код в представлении views.py:
from django.http import HttpResponse
def user_profile(request, user_id):
return HttpResponse(f"Профиль пользователя с ID: {user_id}")
Если вы откроете /profile/42/, вы увидите: "Профиль пользователя с ID: 42".
Типы переменных:
<int:var>— Только целочисленные значения.<str:var>— Любая строка.<slug:var>— URL-friendly строка (буквы, цифры, дефисы).<uuid:var>— UUID.<path:var>— Строка, включающая/.
Работа с urls.py в приложениях
Как уже обсуждалось, каждому приложению в Django свой собственный файл urls.py. Это позволяет модульно проектировать маршруты.
- В
project/urls.pyподключаем маршруты приложения:from django.urls import path, include urlpatterns = [ path('blog/', include('blog.urls')), ]
- В
blog/urls.pyопределяем маршруты:from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('<int:post_id>/', views.detail, name='detail'), ]
Теперь:
http://127.0.0.1:8000/blog/вызоветviews.index.http://127.0.0.1:8000/blog/42/вызоветviews.detail(42).
Проблемы и типичные ошибки
Путаница в синтаксисе
Одна из самых распространённых ошибок — забыть добавить слэш в конце URL, например, path('hello', views.hello_view) вместо path('hello/', views.hello_view). Django строг к этим синтаксическим деталям. Убедитесь, что ваши URL завершены правильным синтаксисом.
Плохая организация маршрутов
Если у вас растёт количество маршрутов, не забудьте модулировать их через include(). Например, держать маршруты приложений в отдельных файлах.
Резюме практики
- Создайте простое представление, которое возвращает текст "Добро пожаловать!".
- Создайте для него маршрут
/welcome/. - Реализуйте динамический маршрут
/user/<int:id>/, который выводит сообщение с ID пользователя. - Попробуйте обработать GET- и POST-запросы в одном маршруте.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ