Курс по Django: https://stepik.org/a/183363
Архив проекта: 61_sitewomen.zip
На прошлом
занятии мы с вами сделали первый шаг по авторизации пользователей на сайте.
Однако в шаблоне авторизации у нас не отображается главное меню. Давайте
поправим этот момент, прежде чем двигаться дальше.
Мы помним, что
приложения в проекте Django следует делать максимально
независимым от друг от друга. Поэтому отображение меню лучше сделать
непосредственно в базовом шаблоне, передавая ему объект-меню, например, в виде
списка. Этот функционал можно реализовать несколькими способами. Используя
только текущие знания, первое, что приходит на ум, это воспользоваться простым пользовательским
тегом. Давайте, для примера, это сделаем. Перейдем в файл women_tags.py и определим simple тег для проброса
списка меню в шаблон:
@register.simple_tag
def get_menu():
return menu
А в шаблоне base.html воспользуемся
им:
Все, теперь
отдельно меню передавать в шаблон не нужно, поэтому в файле women/utils.py уберем его из
класса DataMixin. (Обновляем страницу, видим отображение главного меню.)
Контекстные процессоры
Однако когда
предполагается во все шаблоны проекта передавать какую-либо независимую
информацию, как, например, главное меню, то можно воспользоваться еще одним
механизмом – шаблонными контекстными процессорами. Что это такое? Если открыть
файл settings.py, то в коллекции
TEMPLATES в списке context_processors видим перечисление существующих
контекстов. Например, context_processors.request формирует переменную request во всех наших шаблонах,
а auth.context_processors.auth обеспечивает переменной user. И нам ничто не
мешает создать свой собственный шаблонный контекстный процессор для передачи
списка пунктов главного меню.
В приложении users создадим еще
один вспомогательный файл с именем context_processors.py и в нем
создадим свой контекст для шаблона следующим образом:
from women.utils import menu
def get_women_context(request):
return {'mainmenu': menu}
Как видите, это
невероятно просто! Осталось его прописать в списке других контекстных
процессоров (в файле settings.py):
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'users.context_processors.get_women_context'
],
Все, теперь во
все наши шаблоны будет автоматически передаваться переменная mainmenu со списком
главного меню. Давайте ее используем в шаблоне base.html вместо
переменной menu. А тег, который
пробрасывал переменную menu в шаблон можно убрать.
Вот так легко и
просто можно создавать свои контекстные процессоры для автоматической передачи
глобальной информации во все наши шаблоны. Однако использовать этот механизм
следует только для тех данных, которые так и так передаются во все (или почти
все) шаблоны. Отправлять таким образом какие-либо частные данные не нужно.
Доработка панели главного меню
В заключение занятия
сделаем еще одно изменение. Удалим из списка menu последнюю
строчку для login. Мы пропишем ее
отдельно в шаблоне. Откроем файл base.html и меню будем
формировать следующим образом:
{% block mainmenu %}
<div class="header">
<ul id="mainmenu" class="mainmenu">
<li class="logo"><a href="{% url 'home' %}"><div class="logo"></div></a></li>
{% for m in mainmenu %}
<li><a href="{% url m.url_name %}">{{m.title}}</a></li>
{% endfor %}
<li class="last"><a href="{% url 'users:login' %}">Войти</a></li>
</ul>
<div class="clear"></div>
</div>
{% endblock mainmenu %}
Обратите
внимание, как указано имя маршрута для login. Вначале идет
пространство имен users, а через двоеточие – имя login. Напомню, что
это пространство имен мы с вами определили в файле urls.py пакета
конфигурации, когда подключали через функцию include() файл users/urls.py. Благодаря
этому мы на уровне шаблонов можем четко разграничивать имена маршрутов для
приложения users и других
программных компонент. В частности, если прописать просто имя login, то получим
другой маршрут с этим именем, прописанный в файле women/urls.py.
И последнее, что
мы сделаем – это отобразим в главном меню имя пользователя, если он
авторизован, либо пункт «Войти» и «Регистрация», если не авторизован. Для
этого, опять же в главном шаблоне base.html пропишем
следующую проверку:
{% if user.is_authenticated %}
<li class="last"> {{user.username}} | <a href="{% url 'users:logout' %}">Выйти</a></li>
{% else %}
<li class="last"><a href="{% url 'users:login' %}">Войти</a> | <a href="#">Регистрация</a></li>
{% endif %}
Здесь
используется объект user, связанный с текущим пользователем, и уже у этого
объекта проверяем свойство is_authenticated. Если оно
принимает значение True, значит, пользователь авторизован, иначе – не
авторизован. Для авторизованных пользователей отображается ссылка «Выйти» с
именем маршрута logout. А для неавторизованных ссылки «Войти»
и «Регистрация».
Давайте нажмем
на ссылку «Войти» и в форме авторизации введем данные суперпользователя. Видим,
на панели отобразилось имя пользователя и пункт «Выйти». Нажимаем на выход,
попадаем снова на страницу авторизации.
Курс по Django: https://stepik.org/a/183363