Говоря простым языком, middleware - это промежуточный слой между запросом(request) и ответом (response). В фреймворке Django уже по умолчанию содержатся наиболее важные и нужные middleware. Каждый компонент промежуточного слоя отвечает за определенный функционал. Например, Django предоставляет компонент AuthenticationMiddleware, который ассоциирует пользователей с запросами с помощью сессий. Список предустановленных промежуточных слоев можно посмотреть в файле настроек. Узнать о них подробней можно в официальной документации.
settings.py
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
В процессе выполнения запроса request все middleware выполняются сверху вниз. Это значит, что сначала выполняется SecurityMiddleware
, затем SessionMiddleware
и т.д. На этом этапе для каждого из слоев выполняются два метода process_request()
и process_view()
. На этом этапе Django выполнит всю работу над вашей функцией в пердставлении views.py. Когда обработка функции закончена (получены queryset-ы, сформирована пагинация и т.д.) клиенту возвращается ответ response.
Response возвращается в обратном порядке - снизу в верх и для каждого слоя выполняются методы process_exception()
, process_template_response()
и process_response()
.
Более наглядно увидить мезанизм работы промежуточных слоев можно на картинке.
Создание собственных middleware
Допустим нам необходимо вывысти список категорий товаров. Это можно сделать передав qweryset в представление функции вывода html шаблона, содержащего перечень категорий. Но если нам нужно получать его на каждой странице сайта, например в основном меню сайта, то это проще сделать передачей в base.html. Но ведь base.html не выводиться никаим представлением, в этом и сложность. Вот тут то и приходит на помощь middleware. Для создания собственного промежуточного слоя, необходимо создать новый клас и сохранить его в файле, который надо добавить в settings.py в разделе MIDDLEWARE. Назовем этот файл middleware.py, а класс - GetCategory
и сохраним в приложении myapp.
middleware.py
from django.utils.deprecation import MiddlewareMixin
from printer.models import ProductType
class GetCategory(MiddlewareMixin):
def process_request(self, request):
category_list= ProductType.objects.all()
request.category_list = category_list
return None
Добавим новый промежуточный слой в файл настроек пректа.
settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
...
...
'myapp.middleware.GetCategory',
]
Для доступа к из шаблона необходимо необходимо обращаться через request
html
{% for obj in request.category_list %}
{{ obj.type}}
{% endfor %}