Анонимные посетители должны видеть сайт иным, чем авторизованные пользователи. Авторизованным пользователям должны быть доступны ссылки на страницы регистрации и смены пароля, а анонимным — ссылки на регистрацию и авторизацию.
В Django есть механизм, с помощью которого прямо в шаблоне можно определить, авторизован пользователь или нет. В зависимости от статуса посетителя можно показывать или скрывать определённые фрагменты страницы.
Полезное притаилось в settings.py, в списке context_processors
переменной TEMPLATES
:
# yatube/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
# Вот оно, нужное:
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
]
},
}
]
Перед обработкой шаблона вызываются функции из списка context_processors
. Эти функции могут добавлять в шаблон переменные, к которым можно обратиться: функции изменяют контекст шаблона. Функция django.contrib.auth.context_processors.auth
добавляет в контекст шаблона объект user.
Он может быть двух типов: AnonymousUser, либо экземпляром модели User. Но самое важное — у этого объекта есть свойство is_authenticated
; это свойство принимает значение True
, если пользователь авторизован.
В шаблоне можно проверить, авторизован ли пользователь — и показать авторизованному и неавторизованному разные фрагменты кода:
{# Например, в навигации #}
{% if user.is_authenticated %}
{# Авторизованному пользователю покажем ссылки на выход и смену пароля #}
{% else %}
{# Неавторизованному покажем ссылки на регистрацию и авторизацию #}
{% endif %}
Кастомные контекст-процессоры
По своей природе контекст-процессор — это просто функция, принимающая на вход объект запроса (request
) и возвращающая словарь, к любому элементу которого можно обратиться в любом шаблоне по ключу.Чтобы создать собственный контекст-процессор — надо написать такую функцию и добавить её в список TEMPLATE_CONTEXT_PROCESSORS
.
def welcome(request):
"""Добавляет в контекст переменную greeting с приветствием."""
return {
'greeting': 'Ennyn Pronin: pedo mellon a minno.',
}
После того, как контекст-процессор будет зарегистрирован в TEMPLATE_CONTEXT_PROCESSORS
, в любом шаблоне проекта будет доступна переменная greeting
:
{# Код HTML-шаблона #}
...и на Вратах было начертано: <b>{{ greeting }}</b>
Маленькие хитрости
- Лучше много маленьких контекст-процессоров, чем один большой. Каждый контекстный процессор должен выполнять только одну задачу. Это будет удобно и при тестировании, и при повторном использовании контекст-процессоров в других проектах.
- Переменные из процессора будут доступны во всех шаблонах проекта. Выбирайте имена ключей словаря так, чтобы они не конфликтовали с именами переменных в шаблонах.
- Код контекст-процессоров хранят по-разному, это зависит от традиций, принятых в команде:
- можно создать папку или файл
context_processors
в корне проекта; - в приложении, которое добавляет информацию на все страницы проекта.
- можно сохранить код в отдельном приложении core (мы сделали его для кода, общий для всего проекта).
- можно создать папку или файл
В проекте Yatube хранить контекст-процессоры будем в приложении core, в директории /context_processors.
Подключение процессора к проекту:
# yatube/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
# Добавлен конеткст-процессор
'core.context_processors.year.year',
],
},
},
]
В переводе на человеческий язык эта инструкция будет звучать так:
Найди в корне проекта папку core/
, в ней — папку context_processors/
, там — файл year.py
, а в этом файле — функцию year()
.
Словарь, который она возвращает, добавь на все страницы проекта.
└── yatube
├── posts
├── core
│ ├── context_processors
│ │ ├── __init__.py
│ │ └── year.py
│ ├── templatetags
│ ├── __init__.py
│ └── apps.py
├── templates
├── users
└── manage.py