Django: приложение заметок и именованные адреса
Оглавление курса · Скачать все состояния проекта.
Учебная задача: Отделить приложение notes от настроек проекта и подключить его адреса.
Входное состояние: Снимок lesson-01: корневое представление проекта desk. Выходное состояние: Зарегистрированное notes, пространство имён notes и страница /notes/. Эта глава продолжает «Редакционный стол» — небольшой сайт заметок. Нужны основы Python, HTML и устройство HTTP-запроса. Используем Python 3.12 и Django 5.2.18 LTS; номер ветки выбран для этой серии. Полный каталог lesson-02 в архиве содержит собственные настройки, шаблоны и историю миграций. При самостоятельном прохождении выберите один снимок и отдельную локальную базу; смешивание файлов разных глав меняет договор примера.
Исходники подготовлены редакционным чтением. Зависимости, миграции, сервер и команды работы с данными здесь не выполнялись. Все описанные ответы и изменения являются ожидаемыми, example_execution: not_run.
В первой главе проект отвечал одной функцией из собственного каталога настроек. Теперь выделим предметную часть — заметки редакции — в приложение notes. Проект описывает сайт целиком, приложение объединяет код одной области. Это различие помогает переносить приложение между сайтами и не смешивать записи редактора с настройками HTTP-сервера. На этом шаге мы пока возвращаем строку. Цель урока состоит в том, чтобы читатель мог объяснить, как главный список адресов передаёт остаток пути приложению.
В Django приложение не равно отдельному процессу и не обязательно равно одному экрану. Оно может иметь модели, формы, шаблоны и собственные маршруты. Наше notes будет отвечать за список, карточку и редактирование заметки. Регистрация и вход позже получат собственные представления, а общие настройки останутся в desk. Такое деление основано на смысле данных. Делить программу на папки только ради числа файлов не требуется: главное, чтобы ответственность каждого модуля оставалась понятной.
Регистрация приложения
Класс NotesConfig содержит имя приложения и тип автоматически создаваемого ключа модели. Настройки проекта включают этот класс в INSTALLED_APPS. Список сообщает Django, где искать приложения, их модели, административные регистрации, шаблоны и другие ресурсы. Простое создание каталога на диске не даёт такого сообщения. И наоборот, запись несуществующего имени в настройках приводит к ошибке импорта. Проверьте согласованность имени папки, Python-пакета и строкового имени в конфигурации.
Файл __init__.py делает каталог обычным пакетом Python в нашей структуре. В нём пока нет кода, однако он сохраняется во всех снимках. Не заменяйте его случайным файлом с похожим названием. apps.py описывает конфигурацию, а views.py содержит обработчики запросов. На небольшом сайте все обработчики могут жить в одном файле; по мере роста их допустимо распределять по модулям, не меняя понятие приложения.
Мы не переносим настройки базы в приложение. Все приложения одного учебного сайта используют выбранное подключение из DATABASES. Если позднее вы встретите несколько баз или маршрутизатор запросов к ним, это будет отдельный уровень решений. На текущем шаге появление notes вообще не требует таблицы. Приложение уже может отвечать на запрос, даже если у него нет моделей. Это хорошо показывает, что маршрут и хранение данных не обязаны возникать одновременно.
Передача остатка пути
Главный URLconf связывает префикс notes/ с include("notes.urls"). После совпадения префикса Django передаёт оставшуюся часть пути списку приложения. Поэтому пустой путь в notes.urls означает /notes/ на уровне сайта. Он не заменяет корень сайта и не добавляет название приложения автоматически. Если позже подключить то же приложение под editorial/, его внутренний пустой путь даст /editorial/. Так include отделяет локальную структуру приложения от места подключения.
Внутри notes.urls используется app_name = "notes". Это пространство имён адресов, а не дополнительный сегмент URL. Имя list становится доступно как notes:list. Такой договор пригодится, когда у другого приложения тоже появится маршрут с именем list. Не приходится придумывать глобально уникальные имена для каждой страницы. Пространство имён снимает неоднозначность при построении ссылок и перенаправлений.
В главном списке также есть стандартная административная часть по адресу /admin/. Её наличие не даёт анонимному посетителю полномочий редактора. Доступ к административному интерфейсу проверяется системой пользователей; данные для входа появятся отдельно. На этом уроке не требуется создавать пользователя или входить в панель. Мы лишь сохраняем точку подключения, чтобы последующие главы не меняли главный URLconf без необходимости.
Что происходит с похожими адресами
Порядок маршрутов имеет значение: Django проверяет их последовательно. Сейчас список короткий, поэтому поведение очевидно. Позднее фиксированный путь new/ должен стоять раньше динамического <slug:slug>/, иначе слово new может быть принято за значение карточки. Это не особенность английского слова, а следствие первого подходящего совпадения. Когда добавляете новый путь, рассмотрите его рядом с существующими шаблонами, а не как отдельную строку.
Ожидаемый ответ /notes/ — «Заметки редакции: расписание интервью». Для /notes/unknown/ пока нет совпадения, поэтому ожидается 404. Обратите внимание на завершающий слэш: у нас маршруты записаны со слэшем, и стандартная обработка может перенаправлять вариант без него. Такое перенаправление не создаёт новую карточку. Не полагайтесь на автоматическое исправление пути при разработке формы: адрес действия формы лучше сразу строить правильно по имени.
Для самостоятельной правки добавьте фиксированный маршрут about/ с пояснением назначения редакционного стола. Сначала определите, где должен быть префикс, затем локальное имя. Мысленно восстановите полный адрес и проверьте, что вы не написали notes/ повторно внутри приложения. Если повторить префикс, получится /notes/notes/about/. В следующем уроке представление начнёт передавать данные шаблону, но цепочка разрешения адреса сохранится.
Разбор связи файлов
Путь notes/ в общем маршрутизаторе и путь внутри приложения складываются при обработке запроса. Подключение через include передаёт оставшуюся часть пути, а не полный адрес вместе с доменом. Поэтому перенос всего приложения под другой префикс не требует копировать этот префикс в каждую внутреннюю строку. Эта особенность пригодится, если редакция получит отдельный раздел сайта.
Пространство имён решает другую задачу: отличить имя list заметок от возможного list другого приложения. Оно не ограничивает доступ и не создаёт отдельную сессию. В шаблонах позже будем использовать составное имя notes:list. Обратное построение URL по имени позволяет сохранить ссылку при изменении буквального пути; неправильное имя проявится как ошибка построения адреса, а не как отсутствие данных.
Посмотрите на полный список маршрутов снимка. Административная панель подключена на уровне проекта, а публичная страница находится в приложении notes. Это разделение описывает ответственность, но не запускает два разных сервера. Оба обработчика принадлежат одному Django-проекту и используют одни настройки. Для упражнения мысленно добавьте приложение calendar: его URL можно подключить рядом, не превращая notes/urls.py в перечень всех страниц будущего сайта.
Полные файлы этого шага
Следующие файлы показаны полностью. Остальные согласованные файлы находятся в том же снимке архива; переносите весь каталог при выборе исходного состояния.
notes/apps.py
from django.apps import AppConfig
class NotesConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "notes"
notes/urls.py
from django.urls import path
from . import views
app_name = "notes"
urlpatterns = [path("", views.note_list, name="list")]
desk/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [path("admin/", admin.site.urls), path("notes/", include("notes.urls"))]
notes/views.py
from django.http import HttpResponse
def note_list(request):
return HttpResponse("Заметки редакции: расписание интервью")
Документация и исходники
Механизм этой главы описан в официальной документации Django 5.2. При самостоятельной проверке сначала сопоставьте маршрут, представление и состояние данных, затем сравните результат с указанным ожидаемым поведением. Архив учебного проекта содержит все шестнадцать самостоятельных этапов и договор эксплуатации.