Как передать общие данные во все шаблоны в веб-фреймворках Django и Flask

«Как передать общие данные во все шаблоны в веб-фреймворках Django и Flask» — вопрос из категории Django, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Чтобы избежать дублирования кода и не передавать одни и те же данные (например, имя сайта, меню навигации, информацию о пользователе) из каждой view-функции, в веб-фреймворках используются контекстные процессоры.

Контекстный процессор — это функция, которая принимает объект запроса и возвращает словарь. Этот словарь автоматически добавляется в контекст всех шаблонов.

Django

  1. Создайте функцию контекстного процессора. Обычно её размещают в файле context_processors.py внутри вашего приложения.

    # myapp/context_processors.py
    def project_context(request):
        return {
            'SITE_NAME': 'My Awesome Project',
            'SITE_VERSION': '1.0.2'
        }
  2. Зарегистрируйте его в settings.py.

    # settings.py
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            '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',
                    # Добавляем наш процессор
                    'myapp.context_processors.project_context',
                ],
            },
        },
    ]

    Теперь переменные {{ SITE_NAME }} и {{ SITE_VERSION }} доступны в любом шаблоне проекта.

Flask

Во Flask для этой же цели используется декоратор @app.context_processor.

from flask import Flask

app = Flask(__name__)

@app.context_processor
def inject_global_data():
    # Словарь, который вернет эта функция, будет доступен во всех шаблонах
    return {
        'SITE_NAME': 'My Awesome Flask App'
    }

@app.route('/')
def index():
    # В шаблоне index.html можно использовать {{ SITE_NAME }}
    return render_template('index.html')