Приложение Users. Переопределение шаблона logged_out

Стандартные шаблоны модуля 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, а часть без; коллегам-разработчикам, которым достанется ваш код, придётся угадывать, к какому приложению относятся эти адреса.

Имена шаблонов явно не будут прописаны в рабочем коде — и это точно так же приведёт к игре в угадайку: шаблоны не описаны, но они есть и работают. Где они, как их найти?





Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: