Middleware¶
O Middleware é um framework de hook dentro do processamento de requisição/resposta do Django. Ele é um sistema de “plugins” leve, e de baixo nível para alterar globalmente a entrada ou saída do Django.
Cada componente middleware é responsável por fazer alguma função específica. Por
exemplo, o Django inclui um componente middleware, XViewMiddleware
, que
adiciona um cabeçalho HTTP "X-View"
a toda resposta para uma requisição
HEAD
.
Este documento explica como o middleware funciona, como você ativa o middleware, e como escrever seu próprio middleware. O Django vem com alguns middleware embutidos você pode user; eles são documentados na referência de middlewares embutidos.
Ativando um middleware¶
Para ativar um componente middleware, adicione-o a lista
MIDDLEWARE_CLASSES
no suas configurações do Django. No
MIDDLEWARE_CLASSES
, cada componente middleware é representado por uma
string: o caminho Python completo com o nome da classe middleware. Por exemplo,
o MIDDLEWARE_CLASSES
padrão criado pelo
django-admin.py startproject
:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.doc.XViewMiddleware',
)
Durante as fases da requisição (nos middlewares process_request()
e
process_view()
), o Django aplica o middleware na ordem que está definida
no MIDDLEWARE_CLASSES
, de cima pra baixo. Durante as fases de
repostas (nos middlewares process_response()
e process_exception()
),
as classes são aplicada na ordem inversa, de baixo pra cima. Você pode imaginar
como se fosse uma cebola: cada classe middleware é uma “camada” que envolve a
view:
A instalação do Django não requer qualquer middleware – e.g.,
MIDDLEWARE_CLASSES
pode ser vazio, se você quiser – mas é fortemente
recomendado que você use pelo menos o
CommonMiddleware
.
Escrevendo seu próprio middleware¶
Escrever seu próprio middleware é fácil. Cada componente middleware é uma única classe Python que define um ou mais dos seguintes métodos:
process_request
¶
-
process_request
(self, request)¶
O request
é um objeto HttpResponse
. Este método é
chamado em cada request, antes do Django decidir qual view executar.
O process_request()
deve retornar um None
ou um objeto
HttpResponse
. Se ele retornar None
, o Django
continuará processando a requisição, executando qualquer outro middleware e,
então, a view apropriada. Se ele retorna um objeto
HttpResponse
, o Django não se incomodará em chamar
QUALQUER outra requisição, view ou exceção de middleware, ou a view apropriada;
ele retornará o HttpResponse
.
O middleware de resposta é sempre chamado para todas as respostas.
process_view
¶
-
process_view
(self, request, view_func, view_args, view_kwargs)¶
O request
é um objeto HttpRequest
. O view_func
é
uma função Python que o Django usa. (É o objeto da função atual, não uma string
com o nome da função.) O view_args
é uma lista de argumentos posicionais que
serão passados para o view, e view_kwargs
é um dicionário com argumentos
nomeados que serão passados para o view. Nenhum, view_args
nem
view_kwargs
incluem o primeiro argumento do view (request
).
O process_view()
é chamado logo após o Django chamar o view. Ele deve
retornar um None
ou um objeto HttpResponse
. Se ele
retorna None
, o Django continuará processando esta requisição, executando
qualquer outro middleware process_view()
e, então, a view apropriada. Se ele
retornar um objeto HttpResponse
, o Django não se
incomodará em chamar QUALQUER outra requisição, view ou exceção de middleware,
ou a view apropriada; Ele retornará o HttpResponse
. O
middleware é sempre chamado para todas as repostas.
process_response
¶
-
process_response
(self, request, response)¶
request
is an HttpRequest
object. response
is the
HttpResponse
object returned by a Django view.
process_response()
must return an HttpResponse
object. It could alter the given response
, or it could create and return a
brand-new HttpResponse
.
Diferentemente dos métodos process_request()
é process_view()
, o método
process_response()
é sempre chamado, mesmo que os métodos
process_request()
e process_view()
da mesma classe middleware foram
pulados por causa de um método de um middleware anterior que retornou um
HttpResponse
(isto significa que seu método
process_response()
não pode ivocar a configuração feita em
process_request
, por exemplo). Além do mais, durante a fase de resposta as
classes são aplicadas na ordem reversa, de baixo pra cima. Isto quer dizer que
classes definidas no final da lista MIDDLEWARE_CLASSES
serão
executadas primeiro.
process_exception
¶
-
process_exception
(self, request, exception)¶
O request
é um objeto HttpResponse
. O exception
é
um objeto Exception
lançado por uma função view.
O Django chama process_exception()
quando uma view lança um exceção. O
process_exception()
deve retornar um None
ou um objeto
HttpResponse
. Se ele retorna um objeto
HttpResponse
, a resposta será retornada para o navegador.
Por outro lado, o um manipulador de exceção padrão entra em ação.
Novamente, os middlewares são rodados na ordem inversa durante o processo de
resposta, que inclui process_exception
. Se uma exceção de middleware retorna
uma resposta, nenhuma das classes middlewares acima deste middleware serão
chamadas.
__init__
¶
A maioria das classes middleware não precisam de um inicializador desde que
classes middleware são essencialmente marcadores para os métodos process_*
.
Se você precisar de algum estado global, você pode usar o __ini__
para
configurá-lo. Entretanto, mantenha em mente algumas ressalvas:
- O Django inicializa seus métodos sem qualquer argumento, então você não
pode definir o
__init__
requerendo quaisquer argumentos. - Diferentemente dos métodos
process_*
que são chamados uma vez por requisição,__ini__
é chamado uma somente, quando o servidor Web é iniciado.
Marcando um middleware como inutilizado¶
Algumas vezes é útil determinar, em tempo de execução, se um middleware deve ser
usado. Nestes casos, o método __ini__
de seu middleware pode lançar uma
exceção django.core.exceptions.MiddlewareNotUsed
. O Django irá então remover
este middleware de seu processo de middlewares.
Guidelines¶
- Classes middleware não tem de extender ninguém.
- A classe middleware pode estar em qualquer lugar de seu Python path. Todo
Django se preocupa é com o fato do
MIDDLEWARE_CLASSES
ter o caminho para ele. - Sintá-se livre para olhar em middlewares disponíveis do Django por exemplos.
- Se você escreve um componente middleware que você pensa ser útil para outras pessoas, contribua com a comunidade! Deixe-nos saber, e nós consideraremos adicioná-lo ao Django.