Контекст-процессоры Django

Анонимные посетители должны видеть сайт иным, чем авторизованные пользователи. Авторизованным пользователям должны быть доступны ссылки на страницы регистрации и смены пароля, а анонимным — ссылки на регистрацию и авторизацию.

В 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 




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

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