# Создание профессиональной системы аутентификации пользователей в Django

## Метаданные

- **Спикер:** Corey Schafer
- **Канал:** Corey Schafer
- **Тема:** Изучите процесс интеграции готовых представлений Django для регистрации, входа и выхода пользователей, а также настройки прав доступа для защиты приватных страниц (30 минут).
- **Длительность:** 31:16
- **YouTube:** https://www.youtube.com/watch?v=3aVqWaLjqS4
- **Источник:** https://ekstraktznaniy.ru/workbook/1265

## Ключевые тезисы

1. **Импортируйте встроенные представления аутентификации** — Используйте модуль django.contrib.auth.views для подключения стандартных логик входа и выхода. Это позволяет избежать написания кода с нуля, сохраняя безопасность и стабильность системы.
2. **Определите маршруты (URL patterns)** — Создайте пути для страниц login и logout в файле urls.py вашего проекта. Присвоение имен маршрутам (name='login') позволит использовать их в шаблонах через тег url.
3. **Настройте собственные шаблоны** — Переопределите стандартные пути к шаблонам через аргумент template_name в функции as_view(). Это позволит стилизовать страницы входа и выхода в соответствии с общим дизайном вашего веб-сайта.
4. **Интегрируйте формы авторизации** — Создайте шаблоны login.html и logout.html, используя наследование от базового шаблона. Разместите формы в блоке контента, используя crispy-forms для стилизации элементов.
5. **Настройте параметры перенаправления** — Укажите переменные LOGIN_REDIRECT_URL и LOGIN_URL в файле settings.py. Это гарантирует, что пользователи будут попадать на нужную страницу после входа и принудительно перенаправляться на логин, если не авторизованы.
6. **Добавьте логическую проверку в навигацию** — Используйте переменную user.is_authenticated в базовом шаблоне, чтобы динамически менять пункты меню. Скрывайте или показывайте ссылки 'Login' и 'Logout' в зависимости от состояния сессии пользователя.
7. **Ограничьте доступ с помощью декораторов** — Примените декоратор @login_required к функциям-представлениям, которые требуют авторизации, например, к странице профиля. Это предотвращает доступ неавторизованных пользователей к защищенному контенту.

## Практические задания

### Задание 1: Настройка путей аутентификации

### Задание 2: Создание UI шаблонов

### Задание 3: Настройка логики перенаправления

### Задание 4: Реализация защиты профиля

## Ключевые цитаты

> «Django предоставляет нам множество готовых инструментов для обработки форм и логики аутентификации на бэкенде, однако шаблоны мы создаем сами, чтобы они соответствовали общему стилю нашего сайта.»

> «Использование декоратора @login_required делает защиту представлений максимально простой: если пользователь не авторизован, он автоматически перенаправляется на страницу входа с параметром next, позволяющим вернуться обратно после успешной аутентификации.»

## Полный текст экстракта

# Создание профессиональной системы аутентификации пользователей в Django

> 🎤 **Corey Schafer** — Corey Schafer — известный эксперт по разработке на Python и Django с многолетним опытом преподавания на YouTube.


## ⚡ Зачем читать
* **Безопасность вашего приложения:** Вы перестанете полагаться на «самописные» механизмы сессий и перейдете на проверенные индустриальные стандарты Django, которые защищают от типичных уязвимостей авторизации.
* **Экономия времени:** Использование встроенных представлений (Class-Based Views) позволяет реализовать полнофункциональный цикл "Логин-Логаут" всего за несколько строк кода, делегируя сложную бизнес-логику фреймворку.
* **Улучшение UX:** Вы узнаете, как правильно перенаправлять пользователей, сохранять контекст "куда они хотели попасть" (параметр `next`) и динамически менять интерфейс в зависимости от статуса авторизации.

## 🗺 Карта навыков
| Этап | Задача | Инструмент | Результат |
| :--- | :--- | :--- | :--- |
| 1 | Подключение Auth Views | `django.contrib.auth.views` | Работающие пути /login/ и /logout/ |
| 2 | Кастомизация шаблонов | `template_name` | Уникальный дизайн страниц входа |
| 3 | Настройка редиректов | `settings.py` | Управление потоком навигации пользователя |
| 4 | Ограничение доступа | `@login_required` | Защита приватных страниц (профиль) |

## 1. Интеграция готовых представлений аутентификации
В Django аутентификация — это не просто проверка пароля, это фундаментальный слой системы. Как отмечает Кори Шефер в своем видео, "Django имеет много функциональности, которая уже реализована на бэкенде, поэтому нам не нужно писать логику с нуля". Ваша задача как разработчика — правильно подключить эти "кирпичики". Использование модуля `django.contrib.auth.views` является предпочтительным способом, так как это гарантирует соответствие системы современным стандартам безопасности.

При интеграции представлений в `urls.py` крайне важно следовать именованию. Например, когда вы импортируете `LoginView` и `LogoutView`, используйте конструкцию `as auth_views`. Это предотвращает коллизии имен с вашими собственными представлениями (views) из других приложений. Кори показывает, как создать маршруты: `path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login')`. Обратите внимание на использование `as_view()` — это стандарт для классовых представлений в Django. Этот метод "оживляет" класс, превращая его в функцию, которую может обработать URL-конфигуратор. 

Почему это важно? Если вы начнете писать собственные функции проверки пароля, вы с высокой вероятностью допустите ошибки в хэшировании, обработке сессий или защите от CSRF-атак. Встроенные решения протестированы тысячами разработчиков. В процессе обучения важно понимать, что Django ожидает шаблоны в определенных местах (по умолчанию `registration/login.html`), но вы можете легко переопределить это поведение с помощью параметра `template_name`. Это позволяет хранить все шаблоны авторизации внутри вашего приложения `users`, соблюдая чистоту структуры проекта. Если вы столкнулись с ошибкой "TemplateDoesNotExist", не паникуйте — Django прилежно сообщает в консоли, где именно он искал файл. Просто укажите корректный путь, как показано в уроке, и система подхватит ваш дизайн.

> "Django has a lot of this functionality taken care of for us on the back end already. I'm going to go ahead and get started by using their default login views." — Кори Шефер подчеркивает, что сила фреймворка заключается в разумном использовании его "батареек в комплекте". Это избавляет вас от необходимости "изобретать велосипед" в критически важных узлах системы.

✅ **Сделайте сейчас:** Откройте файл `urls.py` вашего проекта. Импортируйте `auth_views` из `django.contrib.auth.views`. Добавьте два маршрута: для логина и логаута. Убедитесь, что вы явно указали `template_name` для каждого из них, указывая на еще не созданные, но запланированные файлы `login.html` и `logout.html` в папке `users/templates/users/`.

## 2. Настройка потока пользователей и защита приватных зон
После того как формы входа и выхода заработали, следующим логическим шагом является управление "путешествием" пользователя. Django позволяет централизованно управлять перенаправлениями через `settings.py`. Параметры `LOGIN_REDIRECT_URL` и `LOGIN_URL` — это "сердце" навигационного потока. Установка `LOGIN_REDIRECT_URL = 'blog-home'` гарантирует, что после успешной авторизации пользователь попадет именно на главную страницу блога, а не в абстрактный "профиль", который генерирует ошибка 404.

Кори Шефер подробно демонстрирует, как использовать декоратор `@login_required` для защиты страниц. Это элегантное решение: вы просто добавляете одну строку кода над функцией-представлением, и Django берет на себя всю проверку. Если неавторизованный пользователь пытается зайти на страницу, фреймворк перекинет его на страницу входа, автоматически добавив в URL параметр `next`. Это мощнейший инструмент UX: пользователь логинится и сразу оказывается там, куда он хотел попасть изначально. Представьте пользователя, который перешел по прямой ссылке в свой профиль. Если вы не настроите этот механизм, он после логина окажется на главной странице и будет вынужден снова искать кнопку профиля. Благодаря Django, этот "потерянный" переход обрабатывается автоматически.

Также не забывайте про навигацию. Использование переменной `user.is_authenticated` в базовом шаблоне — это "золотой стандарт". Это позволяет динамически переключать меню: если пользователь вошел, показываем "Logout", если нет — "Login" и "Register". Это не только эстетика, но и важная психологическая обратная связь: пользователь всегда понимает свой статус в системе. Помните: "Если вы не даете пользователю обратную связь, он чувствует себя потерянным". Даже такая мелочь, как скрытие кнопки входа для уже залогиненного пользователя, делает приложение профессиональным и завершенным. При разработке страницы профиля, как показано в видео, используйте этот декоратор обязательно, чтобы закрыть доступ любому, кто не прошел аутентификацию.

> "There's one really nice thing that I want to show you here that's built into the Django login view. It's keeping track of the page that we were trying to access and it will direct us to that page after the login." — Кори акцентирует внимание на том, что Django "помнит" намерения пользователя. Это пример того, как глубокое понимание фреймворка упрощает жизнь разработчику и улучшает продукт для конечного пользователя.

✅ **Сделайте сейчас:** Перейдите в `settings.py` и добавьте константы `LOGIN_REDIRECT_URL` и `LOGIN_URL`. Затем в `views.py` вашего приложения `users` импортируйте `login_required` и примените этот декоратор к представлению `profile`. Протестируйте систему: попробуйте зайти по адресу `/profile/` будучи "вылогиненным" — система должна перенаправить вас на логин.

---

## 3. Создание динамического интерфейса и навигации

Теперь, когда механизмы логина и логаута функционируют, пришло время сделать наш пользовательский интерфейс «умным». В профессиональной разработке пользователь не должен видеть кнопку «Войти», если он уже авторизован. Это создает когнитивную нагрузку и выглядит непрофессионально. Как отмечает Кори Шефер в своем видео: «Всегда полезно давать пользователям визуальную обратную связь, сообщая им, вошли они в систему или нет». Использование Django-шаблонизатора позволяет нам управлять видимостью элементов на лету с помощью встроенной переменной `user`.

В файле `base.html` (или в вашем глобальном шаблоне навигации) мы используем мощный объект `user`, который доступен в контексте любого шаблона благодаря `AuthenticationMiddleware`. Ключевой атрибут здесь — `is_authenticated`. Это логическое значение, которое возвращает `True`, если сессия пользователя активна. В видео Кори демонстрирует, как обернуть пункты меню в конструкцию `{% if user.is_authenticated %}...{% else %}...{% endif %}`. Это не просто скрытие кнопок; это управление состоянием приложения. Если пользователь авторизован, мы отображаем ссылку на «Профиль» и «Выход» (Logout). Если нет — показываем «Войти» (Login) и «Регистрация» (Register). Важно помнить: если вы попытаетесь использовать тег `{% url 'login' %}` до того, как определите этот маршрут в `urls.py`, Django выбросит ошибку. Поэтому порядок разработки всегда должен быть: маршруты -> шаблоны -> динамика навигации.

Почему это критически важно? Представьте, что пользователь зашел на ваш сайт, авторизовался, но в навигации по-прежнему видит кнопку «Войти». Он нажмет на неё, перейдет на страницу авторизации, увидит форму — это вызывает недоумение. Динамическая навигация решает проблему UX-разрыва. Также обратите внимание на именование ссылок. Мы используем тег `{% url 'logout' %}`, который обращается к `name='logout'` в конфигурации URL. Это делает код гибким: если вы решите изменить адрес страницы с `/logout/` на `/sign-out/`, вам не придется править каждый шаблон — достаточно изменить один путь в `urls.py`.

> "It's always a good idea to give your users some visual feedback like that letting them know whether they're logged in or logged out because if they're logged in and they see a login/register route at the top then it's going to kind of confuse them and make them think that they're not currently logged in." — Кори Шефер подчеркивает, что визуальная чистота интерфейса напрямую влияет на доверие пользователя к вашему веб-приложению.

✅ **Сделайте сейчас:** Откройте ваш базовый шаблон `base.html`. Найдите блок `<nav>` и реализуйте конструкцию `if/else`, используя `user.is_authenticated`. Убедитесь, что внутри блока `if` у вас есть ссылка на `profile` и `logout`, а внутри блока `else` — на `login` и `register`. Перезагрузите страницу и проверьте, как меняется меню при смене статуса сессии.

## 4. Защита маршрутов через декораторы доступа

Завершающим этапом создания системы аутентификации является ограничение доступа к приватным страницам. Одной лишь визуальной скрытости ссылки «Профиль» недостаточно. Если злоумышленник знает путь `/profile/`, он сможет открыть его напрямую, даже не будучи авторизованным. Чтобы предотвратить это, Django предлагает декораторы представлений. Декоратор `@login_required` — это «страж» ваших методов. Он оборачивает функцию-представление и проверяет, существует ли активная сессия у пользователя, делающего запрос.

В видео Кори Шефер показывает создание представления `profile` в `views.py`. Он импортирует декоратор `from django.contrib.auth.decorators import login_required` и применяет его над функцией: `@login_required`. Когда неавторизованный пользователь обращается к `/profile/`, декоратор перехватывает запрос и перенаправляет его на страницу логина. При этом Django делает «магическую» вещь: он добавляет к URL параметр `?next=/profile/`. Благодаря этому параметру, после успешного ввода логина и пароля, Django автоматически вернет пользователя именно на ту страницу, которую он хотел посетить изначально. Это лучший стандарт индустрии, который избавляет пользователя от необходимости искать путь в личный кабинет повторно.

Важный нюанс, который часто упускают новички: если вы не настроили `LOGIN_URL` в `settings.py`, Django по умолчанию будет искать путь `/accounts/login/`, который вы, скорее всего, не создавали (мы ведь определили его как `/login/`). Поэтому в блоке настроек обязательно пропишите `LOGIN_URL = 'login'`, где `'login'` — это имя вашего URL-паттерна. Это связующее звено, которое позволяет декоратору `@login_required` знать, куда именно отправлять «незваных гостей». Использование декораторов — это самый чистый способ защиты в Django, так как он отделяет логику проверки доступа от бизнес-логики отображения профиля. Вы не пишете громоздкие `if request.user.is_authenticated: ... else: return redirect(...)` внутри каждой функции, а просто «декорируете» их, что делает ваш код легко читаемым и масштабируемым. Это и есть профессиональный подход: лаконичность, читаемость и надежность, встроенные в каркас самого фреймворка, который уже протестирован на миллионах запросов по всему миру.

---

## 5. Работа с контекстом пользователя в шаблонах

Когда мы создаем систему аутентификации, важно не просто «спрятать» ссылки, но и обеспечить бесшовный пользовательский опыт внутри самого приложения. В Django объект `user` является «гражданином первого класса». Он автоматически добавляется в контекст шаблона благодаря `AuthenticationMiddleware`. Это означает, что в любой части вашего HTML-кода вы можете обратиться к `{{ user }}`. Если пользователь не залогинен, это будет объект `AnonymousUser`, если залогинен — экземпляр модели `User`. Понимание этого механизма — ключ к созданию персонализированных интерфейсов, о которых говорит Кори Шефер в своем курсе.

Кори наглядно демонстрирует, как использовать этот объект для отображения имени пользователя на странице профиля. В файле `profile.html` он использует конструкцию `{{ user.username }}`. Это лаконичное решение избавляет от необходимости вручную передавать данные пользователя из функции-представления в словарь `context`. Django делает всю «черную» работу за вас. Если вы хотите сделать интерфейс еще более дружелюбным, вы можете использовать этот объект для вывода email-адреса, даты регистрации или даже аватара, если вы расширите профиль пользователя в будущем. 

Однако здесь кроется и важный момент безопасности: никогда не доверяйте данным, которые приходят извне, но в рамках шаблонизатора Django все переменные автоматически проходят этап экранирования. Это защищает вас от XSS-атак (Cross-Site Scripting). Представьте, что пользователь зарегистрировался под именем `<script>alert('hack')</script>`. Без автоматического экранирования Django этот код исполнился бы в браузере каждого, кто зашел на страницу профиля. Но Django по умолчанию выводит данные как безопасный текст. Как методист с многолетним стажем, я подчеркиваю: используйте встроенные возможности шаблонизатора, не пытайтесь «изобретать велосипеды» с сырым HTML-выводом.

Кроме того, помните о логике «пустого состояния». Если вы выводите данные пользователя, предусмотрите, что будет, если поле не заполнено. Например, вместо простого `{{ user.profile.bio }}`, используйте фильтр `default`, например: `{{ user.profile.bio|default:"Пользователь еще не рассказал о себе." }}`. Это делает интерфейс «живым» и готовым к любым сценариям, даже самым неожиданным.

> "And remember that user is not something that we actually have to pass in to the context that is something that is built into Django that represents the current logged in user." — Кори напоминает, что Django — это фреймворк, ориентированный на продуктивность, где большинство инфраструктурных задач уже решены на уровне middleware, что освобождает разработчика для решения бизнес-задач.

✅ **Сделайте сейчас:** Создайте страницу профиля `profile.html`. Внутри блока контента выведите приветствие: `<h1>Привет, {{ user.username }}!</h1>`. Добавьте ниже вывод email: `<p>Ваш email: {{ user.email }}</p>`. Проверьте, отображаются ли данные корректно после входа в систему. Попробуйте изменить имя пользователя в админ-панели и обновите страницу — убедитесь, что данные обновляются динамически.

## 6. Гибкая настройка перенаправлений и UX-паттерны

Профессиональная система авторизации определяется не только тем, как пользователь входит, но и тем, как он перемещается по сайту после этого. В Django есть мощный механизм, который часто недооценивают — параметр `next` в строке запроса. Когда вы защищаете представление декоратором `@login_required`, Django не просто «выбрасывает» пользователя на страницу логина. Он «запоминает» URL, на который пользователь хотел попасть изначально, и передает его в GET-параметре, например: `?next=/profile/`. 

Кори Шефер делает на этом особый акцент, называя это «ожидаемым поведением современных веб-приложений». Вспомните, как работают крупные сервисы: если вы перешли по ссылке на «Избранное», не будучи авторизованным, система предложит вам войти, а после успешного ввода пароля автоматически вернет именно в «Избранное», а не на главную страницу. В Django это работает «из коробки» при использовании стандартных `LoginView`. Однако, если вы начнете переопределять логику перенаправлений, важно не сломать этот паттерн. 

Настройка `LOGIN_REDIRECT_URL` в `settings.py` — это лишь «запасной вариант». Если параметр `next` в URL отсутствует, Django отправит пользователя по этому адресу. Но если вы используете стандартную форму Django, она учитывает наличие `next`. Как разработчик, вы должны стремиться к тому, чтобы навигация пользователя была максимально предсказуемой. Если ваш сайт — это сложный веб-портал, возможно, вам потребуется динамически менять `next`, но для 95% случаев достаточно просто корректно настроить глобальный `LOGIN_REDIRECT_URL`. 

Также обратите внимание на именование маршрутов. Кори использует `name='login'`, `name='logout'`, `name='profile'`. Это «золотое правило» Django. Никогда не хардкодьте URL-адреса в шаблонах (например, `href="/login/"`). Используйте тег `{% url 'login' %}`. Почему? Потому что, если через полгода вы решите перенести логин на путь `/auth/sign-in/`, вам придется менять только один файл `urls.py`, а не сотни шаблонов. Это называется принципом DRY (Don't Repeat Yourself), и в контексте навигации он жизненно необходим для масштабируемости проекта.

> "It's keeping track of the page that we were trying to access and it will direct us to that page after the login... that's a feature that most people expect on web apps these days." — Кори подводит итог важности UX-деталей, которые отделяют «любительскую поделку» от полноценного продукта, где пользователь чувствует, что система работает для него, а не он для системы.

✅ **Сделайте сейчас:** Проверьте ваши шаблоны `base.html`, `login.html` и `logout.html`. Убедитесь, что все ссылки оформлены через тег `{% url '...' %}`. Затем принудительно перейдите по URL `/profile/` будучи неавторизованным. Убедитесь, что в адресной строке после перенаправления на `/login/` появляется параметр `?next=/profile/`. Успешно залогиньтесь и пронаблюдайте за автоматическим возвратом на страницу профиля.

---

## 7. Работа с сообщениями (Messages Framework) и обратная связь

В процессе создания системы аутентификации мы часто забываем о самом важном аспекте: «диалоге» с пользователем. Когда человек нажимает кнопку «Войти» или «Зарегистрироваться», он ожидает подтверждения того, что система его поняла. Django предоставляет мощный механизм для этих целей — `Messages Framework`. Это встроенный инструмент, который позволяет передавать пользователю кратковременные уведомления, такие как «Ваш аккаунт успешно создан» или «Вы успешно вышли из системы». Кори Шефер уделяет этому внимание как средству улучшения UX, ведь отсутствие визуальной реакции от сайта после критических действий заставляет пользователя чувствовать себя неуверенно.

В коде регистрации мы часто используем функцию `messages.success()`. Это выглядит как `messages.success(request, f'Account created for {username}!')`. Важно понимать, что эти сообщения сохраняются в сессии пользователя или в cookies, что позволяет им «пережить» перенаправление (redirect). Без этой системы, если вы просто передадите переменную в шаблон, она исчезнет при первой перезагрузке страницы. Framework сообщений гарантирует, что уведомление будет показано именно тогда, когда пользователь попадет на целевую страницу.

Чтобы вывести эти сообщения в шаблоне, мы используем цикл в `base.html`. Кори демонстрирует конструкцию `{% for message in messages %}`. Это не просто вывод текста, это возможность добавить стилизацию через классы CSS. Например, используя Bootstrap, мы можем присвоить сообщению класс `alert-success` для зеленых уведомлений или `alert-danger` для ошибок. Как методист, я настоятельно рекомендую: всегда визуализируйте результат действия. Если пользователь сменил пароль или обновил профиль, он должен видеть «зеленую плашку» с успехом. Это фундамент доверия к интерфейсу.

Помимо стандартных уровней (info, success, warning, error), вы можете создавать свои, но для 99% задач хватает встроенных. Главное правило: не перегружайте пользователя уведомлениями. Сообщение должно быть кратким, понятным и содержать призыв к действию, если это необходимо. Помните: хороший интерфейс говорит пользователю, что произошло, а плохой — заставляет гадать, сохранились ли данные.

> "The messages framework allows you to temporarily store messages in one request and then display them in the next request." — Кори акцентирует внимание на том, что это идеальный инструмент для передачи данных между запросами без использования сложных баз данных или глобальных переменных.

✅ **Сделайте сейчас:** В вашем файле `base.html` сразу после блока навигации добавьте блок для вывода сообщений. Используйте цикл `for` по переменной `messages`. Оберните вывод в `div` с классами Bootstrap `alert alert-{{ message.tags }}`. Теперь в представлении регистрации (`views.py`) добавьте `messages.success(request, 'Аккаунт успешно создан!')` перед редиректом. Проверьте отображение сообщения после регистрации нового пользователя.

## 8. Именование маршрутов и масштабируемость проекта

Когда ваш проект перерастает десяток страниц, хардкодинг путей (например, `<a href="/login/">`) становится «бомбой замедленного действия». Как опытный методист, я заявляю: использование имен маршрутов (URL names) — это не прихоть Django, а критическая необходимость для поддержки кода. В видео Кори Шефер постоянно акцентирует внимание на аргументе `name` в функции `path()`. Когда мы пишем `path('login/', auth_views.LoginView.as_view(), name='login')`, мы создаем абстракцию. Теперь в любом шаблоне мы можем вызвать `{% url 'login' %}`, и Django сам подставит текущий актуальный URL.

Почему это важно? Представьте, что через полгода вы решили изменить структуру сайта. Теперь логин находится по адресу `/auth/login/`. Если вы использовали «жесткие» ссылки, вам придется вручную искать и заменять `/login/` во всех файлах проекта. Если вы использовали `{% url 'login' %}`, достаточно изменить один путь в файле `urls.py`. Это делает ваш код «защищенным от изменений» (change-resilient). Это профессиональный стандарт, который разделяет логику маршрутизации и презентации.

Кроме того, использование `name` позволяет избежать конфликтов пространств имен. Если у вас несколько приложений (например, `blog` и `users`), вы можете использовать `app_name`. Тогда обращение к ссылке превращается в `{% url 'users:login' %}`. Это предотвращает ситуацию, когда разные приложения случайно используют одинаковые имена для URL. Это архитектурное мышление, которое отделяет новичка от специалиста.

Также стоит упомянуть передачу аргументов в URL. Если вы используете `path('post/<int:pk>/', ... , name='post-detail')`, вы можете использовать ссылку `{% url 'post-detail' post.pk %}`. Это динамика, которая делает систему мощной и гибкой. Никогда не пишите пути вручную. Если вы видите в своем шаблоне `href="/profile/"`, знайте — это технический долг, который нужно немедленно исправить.

> "You should use the URL tag instead of hardcoding the URL paths because that allows you to change the URL structure in one place without breaking your templates." — Кори подчеркивает, что правильное использование системы URL-конфигурации — это ключ к чистому и поддерживаемому коду в долгосрочной перспективе.

✅ **Сделайте сейчас:** Проведите ревизию всех ваших шаблонов. Найдите все ссылки, где путь прописан как строка (начинается с `/`). Замените их на тег `{% url 'имя_маршрута' %}`. Убедитесь, что для каждого маршрута в `urls.py` задан уникальный параметр `name`. Проверьте, что после рефакторинга все переходы между страницами работают корректно.

## 🏋️ Практикум
1. Добавьте в `settings.py` переменную `LOGOUT_REDIRECT_URL = 'blog-home'`, чтобы после выхода пользователь сразу попадал на главную страницу.
2. Реализуйте в `base.html` проверку `{% if user.is_authenticated %}`, чтобы кнопка «Профиль» отображалась только авторизованным пользователям.
3. Создайте кастомный стиль для сообщений об ошибках в `base.html`, используя `alert-danger` для сообщений уровня `error`.
4. Добавьте в шаблон `login.html` ссылку «Забыли пароль?», даже если она пока ведет на пустую страницу (для закрепления структуры шаблонов).
5. Переименуйте маршрут профиля в `urls.py` на `user-profile` и обновите все ссылки в навигации, чтобы увидеть, как работает система именования.
6. Добавьте декоратор `@login_required` не только на функцию профиля, но и на гипотетическую функцию редактирования поста (если она создана).

## 🔑 Итоги: 5 действий на сегодня
1. Настройте `LOGIN_URL` и `LOGIN_REDIRECT_URL` в `settings.py` для бесшовного UX.
2. Внедрите `messages framework` для обратной связи пользователю при входе/выходе.
3. Переведите все ссылки в шаблонах на `{% url %}` для соблюдения принципа DRY.
4. Защитите все приватные представления декоратором `@login_required`.
5. Протестируйте сценарий «попытка входа на закрытую страницу -> редирект на логин -> возврат на закрытую страницу после авторизации».

## 💬 Цитаты для вдохновения
- "Always keep your users informed about what is happening on your site, because clarity is the best feature you can build." 
- "The path to professional development is not about knowing every function, but about mastering the architectural patterns like decorators and middleware that Django gives you."}