Ответ
Django обрабатывает URL-адреса с помощью механизма URL-диспетчера (URL dispatcher). Его основная задача — сопоставить запрошенный URL с конкретной функцией или классом-представлением (view), который сгенерирует ответ.
Процесс состоит из следующих шагов:
- Входная точка: Веб-сервер передает запрос Django. Django определяет корневой файл URL-конфигурации (обычно
urls.pyв папке проекта), указанный в настройкеROOT_URLCONF. - Поиск по
urlpatterns: Django последовательно перебирает все шаблоны в спискеurlpatternsв этом файле. - Первое совпадение: Как только находится первый шаблон, соответствующий запрошенному URL, поиск прекращается.
- Вызов View: Django вызывает связанную с этим шаблоном view-функцию, передавая ей объект
HttpRequestи любые параметры, извлеченные из URL (например,yearизarticles/<int:year>/). - Генерация ответа: View-функция обрабатывает запрос и возвращает объект
HttpResponse.
Пример urls.py:
from django.urls import path
from . import views # views.py в том же приложении
urlpatterns = [
# URL: /articles/
path('articles/', views.article_list, name='article-list'),
# URL: /articles/2023/
# <int:year> - это "конвертер пути", который захватывает целое число
# и передает его в view как аргумент `year`
path('articles/<int:year>/', views.article_archive, name='article-archive-year'),
]
Ключевые особенности системы:
- Конвертеры путей (Path Converters): Использование
int:,slug:,str:для автоматического захвата и преобразования типов параметров из URL. - Обратный вызов URL (Reverse URL resolving): Использование имен (
name='article-list') для генерации URL в шаблонах и коде ({% url 'article-list' %}), что делает код более гибким и устойчивым к изменениям. - Вложенные
urlpatterns: Возможность подключать файлыurls.pyиз отдельных приложений с помощью функцииinclude(), что способствует модульности. - Регулярные выражения: Для сложных шаблонов можно использовать
re_path()вместоpath().
Ответ 18+ 🔞
А, ну это же про то, как Джа́нго, этот упоротый фреймворк, решает, куда какой запрос послать! Слушай, тут всё просто, если не заморачиваться.
Представь себе, что твой сайт — это такой огромный, блядь, сортировочный центр для писем, а URL dispatcher — это главный дед-начальник, который смотрит на адрес на конверте и орёт: «Эту папку — в третий кабинет, а эту хуйню с цифрами — Иванову на обработку!».
Вот как этот цирк работает, по шагам:
- Входная дверь. Веб-сервер приносит конверт с адресом (URL) в приёмную Джа́нго. Джа́нго сразу лезет в главный справочник (
ROOT_URLCONF) и находит там основной файл правил — обычно этоurls.pyв папке проекта. Это типа устав сортировочного центра. - Чтение устава. Джа́нго открывает этот файл и видит там священный список под названием
urlpatterns. Это просто перечень всех возможных адресных шаблонов и указаний, что с ними делать. - Поиск совпадения. Он начинает сверять адрес на конверте с каждым шаблоном в списке, сверху вниз. Как только находит первое, блядь, совпадение — всё, поиск окончен. Остальные шаблоны он даже не смотрит, ленивая жопа.
- Передача дела. Нашёл шаблон — увидел, какая функция-обработчик (view) к нему привязана. Джа́нго вызывает эту функцию, суёт ей в руки сам конверт-запрос (
HttpRequest) и все вытащенные из адреса параметры (типа год, номер статьи — об этом ниже). - Получение ответа. Функция там внутри что-то делает, думает, и в конце концов выплёвывает готовый ответ (
HttpResponse) — HTML-страницу, JSON или просто «404, иди нахуй».
Вот смотри, как это выглядит в коде (urls.py):
from django.urls import path
from . import views # Импортируем наши функции-обработчики из соседнего файла
urlpatterns = [
# Если пришёл запрос на /articles/ — зови функцию views.article_list
path('articles/', views.article_list, name='article-list'),
# А вот это интереснее! Если запрос типа /articles/2024/
# <int:year> — это конвертер пути. Он выцепит из URL число (2024),
# проверит, что это действительно int, и передаст его в функцию
# как аргумент с именем `year`. Удобно, ёпта!
path('articles/<int:year>/', views.article_archive, name='article-archive-year'),
]
А теперь про крутые фишки, без которых жить нельзя:
- Конвертеры путей (Path Converters): Это вот эти штуки
<int:year>,<slug:post_slug>. Они не просто кусок текста из адреса вырывают, а ещё и приводят его к нужному типу.int:— к числу,slug:— к строке без пробелов и спецсимволов. Если вint:попадёт буква — Джа́нго просто скажет «не нашёл» и пойдёт дальше по списку. Красота! - Обратный поиск URL (Reverse resolving): Ты даёшь каждому пути имя (
name='article-list'). А потом в шаблонах или коде просто говоришь: «Джа́нго, дай мне URL для 'article-list'». И он тебе его сам сгенерирует! Поменял путь вurls.py— и он автоматически везде обновится. Это овердохуище удобно, чтобы не плодить хардкод. - Вложенность (include): Чтобы в главном
urls.pyне было пиздеца на тысячу строк, можно подключатьurlpatternsиз отдельных приложений. Типаpath('blog/', include('blog.urls')). Получается модульно и чисто. - Регулярки (re_path): Если твои шаблоны адресов настолько ебнутые, что стандартными
path()не описать — всегда можно, блядь, выкатить тяжёлую артиллерию в виде регулярных выражений черезre_path(). Но это уже для извращенцев.
Вот и вся магия. Ничего сложного, просто система указателей: увидел адрес — отправил в нужную функцию. Главное — шаблоны правильно написать и не запутаться в порядке их следования, а то твой запрос упрётся в первую же регулярку и дальше не пойдёт.