Стандартные шаблоны модуля django.contib.auth не подойдут для вашего проекта: чтобы дизайн всех страниц был в одном стиле — потребуется изменить HTML-вёрстку страницы.
Шаблоны модуля хранятся в виртуальном окружении, и нельзя просто взять и изменить их код: это не приведёт ни к чему хорошему.
Директория с виртуальным окружением исключена из Git (нет смысла замусоривать Git лишними файлами из /venv). Следовательно, в Git не попадут и отредактированные шаблоны.В результате другой разработчик при установке проекта скачает и развернёт на своём компьютере «чистое» виртуальное окружение, в котором не будет этих отредактированных шаблонов.
Идея «отслеживать директорию /venv через Git» тоже не годится: в этой папке содержатся тысячи файлов, и гонять их через Git — неудобно и нерационально.
Все файлы, в которые вы внесли изменения, должны храниться в рабочей директории проекта.Вместо стандартных файлов приложению можно «подложить» собственные, размещённые в рабочей директории. Это могут быть и HTML-шаблоны, и, при необходимости, views.
Для этого в проекте создают отдельное приложение, перенаправляют в него URL, предназначенные для работы django.contib.auth. В новом приложении можно переопределить шаблоны и внести какие-то другие изменения в работу стандартного приложения: например, именно в этом приложении будет удобно настроить систему регистрации нового пользователя.Так и поступим.
Создание приложения users
Создайте в проекте Yatube приложение users; проще всего сделать это через консоль: приложение posts вы создавали именно этим способом. Активируйте виртуальное окружение (если оно ещё не активно) — и вперёд:
(venv)...$ python3 manage.py startapp users
Эта колдограмма
создаст каркас приложения: директорию для приложения и набор основных файлов.
Файл urls.py в приложении, папку для шаблонов и сами шаблоны нужно будет создать руками.
└── yatube
├── posts
├── users # создастся автоматически
│ ├── __init__.py
│ ├── migrations/
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py # Этот файл нужно создать
│ └── views.py
├── templates
│ ├── includes/
│ ├── posts/
│ ├── users/ # Эту директорию для шаблонов нужно создать руками
│ └── base.html
└── manage.py
Зарегистрируйте приложение users в списке INSTALLED_APPS
в файле settings.py: **добавьте в этот список строчку 'users.apps.UsersConfig'
.Всё! Приложение users подключено и готово к работе.
Перенаправляем запросы в новое приложение
Задача приложения users — расширить и изменить работу встроенного приложения django.contrib.auth. Для этого, в первую очередь, нужно перенаправить все запросы, начинающиеся с /auth , в новое приложение. Важно, чтобы в головном списке urlpatterns
пути приложения users были размещены выше, чем пути приложения django.contrib.auth.
# yatube/urls.py
from django.conf import settings
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
...
# Django проверяет url-адреса сверху вниз,
# нам нужно, чтобы Django сначала проверял адреса в приложении users
path('auth/', include('users.urls', namespace='users')),
# Если какой-то URL не обнаружится в приложении users —
# Django пойдёт искать его в django.contrib.auth
path('auth/', include('django.contrib.auth.urls')),
...
]
Готово. Все запросы, которые раньше обрабатывались в django.contrib.auth, теперь идут в приложение users. Если же какой-то запрос не описан в users — Django пойдёт искать его в приложение django.contrib.auth. Всё будет работать, даже если файл users/urls.py будет вообще пуст.
Переназначение шаблона logged_out.html
Теперь в файле users/urls.py нужно для каждого из адресов указать обработчик, view-функцию или view-класс. В приложении users нет обработчиков, но писать их и не придётся: импортируем и подключим готовые view-классы из django.contrib.auth, ведь они специально написаны для обработки тех запросов, которые мы перехватили и направили в users.
С этого момента приложение users начнёт приносить реальную пользу. Попрактикуемся на простом примере: подменим шаблон страницы, которая показывается пользователю при выходе из системы.
- Адрес страницы: auth/logout/
- Обработчик:
django.contrib.auth.views.LogoutView
- HTML-шаблон страницы: подсунем свой!
В файле users/urls.py настроим path()
для auth/logout/ так, чтобы применялись views из django.contrib.auth, а HTML-шаблоны — из приложения users. Перед этим импортируем нужный view-класс из django.contrib.auth.views
, а то ничего не заработает.
# users/urls.py
# Импортируем из приложения django.contrib.auth нужный view-класс
from django.contrib.auth.views import LogoutView
from django.urls import path
app_name = 'users'
urlpatterns = [
path(
'logout/',
# Прямо в описании обработчика укажем шаблон,
# который должен применяться для отображения возвращаемой страницы.
# Да, во view-классах так можно! Как их не полюбить.
LogoutView.as_view(template_name='users/logged_out.html'),
name='logout'
),
]
Теперь при обработке запроса auth/logout/ будет использоваться контент, генерируемый LogoutView
, а шаблон будет взят из папки templates/users/logged_out.html
Осталось разместить свой шаблон по этому адресу. Его код будет таким:
{# Это код файла templates/users/logged_out.html #}
{% extends 'base.html' %}
{% block title %}Вы вышли из системы{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8 p-5">
<div class="card">
<div class="card-header">
Выход
</div>
<div class="card-body">
<p>
Вы вышли из своей учётной записи. Ждём вас снова!
</p>
</div> <!-- card body -->
</div> <!-- card -->
</div> <!-- col -->
</div> <!-- row -->
{% endblock %}
Чит для ленивых
Чтобы приложение django.contrib.auth применяло кастомные шаблоны — не обязательно создавать приложение и перехватывать запросы. Можно в директории, где хранятся HTML-шаблоны всего проекта, создать папку registration
и поместить в неё собственные шаблоны, названные так же, как они называются в django.contrib.auth.
Например, если разместить шаблон logged_out.html
так, как показано в листинге — view-класс LogoutView
автоматически применит его для адреса /auth/logout/ безо всяких дополнительных приложений и перенаправлений.
└── yatube
├── posts
├── users
├── templates
│ ├── includes
│ ├── posts
│ ├── registration
│ │ └── logged_out.html
│ ├── users
│ └── base.html
└── manage.py
Если имена шаблонов и относительный путь к ним от головной директории /templates будут полностью совпадать с именами и путями в django.contrib.auth — для отображения страниц будут применены кастомные шаблоны.Но у этого подхода есть несколько недостатков.В приложении django.contrib.auth не прописаны namespace
для адресов, а значит, для ссылок на страницы этого приложения нельзя будет использовать адреса вида namespace:name
; вместо ожидаемого {% url 'users:logout' %}
придётся указывать адреса только через name
из приложения django.contrib.auth: {% url 'logout' %}
. А чтобы выяснить эти name
— нужно покопаться в директориях виртуального окружения (для Windows придётся добираться до адреса …\venv\Lib\site-packages\django\contrib\auth\urls.py, не ближний путь).
Отсутствие namespace
нарушит консистентность кода: часть адресов будет с namespace
, а часть без; коллегам-разработчикам, которым достанется ваш код, придётся угадывать, к какому приложению относятся эти адреса.
Имена шаблонов явно не будут прописаны в рабочем коде — и это точно так же приведёт к игре в угадайку: шаблоны не описаны, но они есть и работают. Где они, как их найти?