Como criar Middlewares no Django

Cansado de programar?

Cansado(a) de quebrar a cabeça para aprender a programar Python de verdade?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Suporte

Projetos práticos voltados para o mercado de trabalho

Suporte

Formação moderna com foco na prática profissional

Fala Dev! Na paz?!

Nesse post vamos aprender a criar Middlewares no Django, que são trechos de código para tratamento prévio ou posterior das requisições que chegam e saem do seu sistema Django.

Ficou confuso? Então bora pro post! :wink:

Mas antes, um aviso!

Esse post faz parte do contexto da Série Django aqui da Python Academy!

Já se liga nos outros posts:

:ballot_box_with_check: Django: Introdução ao framework
:ballot_box_with_check: Django: A Camada Model
:ballot_box_with_check: Django: A Camada View
:ballot_box_with_check: Django: A Camada Template

Agora sim, bora!

Vá Direto ao Assunto…

Mas primeiro...

Eu disponibilizei gratuitamente a aula introdutória do nosso Curso de Django - que é parte integrante do curso Jornada Python, aqui da Python Academy - e acho que você pode aprender bastante com ela!

Nesse vídeo você vai aprender sobre:

  • Desenvolvimento Frontend vs Backend
  • Arquitetura do Django
  • Por que aprender Django
  • O mercado para o Desenvolvedor Django
  • O salário do Dev Django trabalhando para fora
  • Quais empresas utilizam o Django

É só clicar na imagem abaixo para assistir o vídeo!

O que são Middlewares

Middlewares são trechos de códigos que podem ser executados antes ou depois do processamento de requisições/respostas pelo Django.

É uma forma que os desenvolvedores, nós, temos para alterar como o Django processa algum dado de entrada ou de saída.

Se você olhar no arquivo settings.py, nós temos a lista MIDDLEWARE com diversos middlewares pré-configurados:

1
2
3
4
5
6
7
8
9
MIDDLEWARE = [
    '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',
]

Por exemplo, o middleware AuthenticationMiddleware é reponsável por adicionar a variável user a todas as requisições.

Dessa forma, você pode, por exemplo, mostrar o usuário logado no seu template:

1
2
3
<li>
    <a href="{% url 'profile' id=user.id %}">Olá, {{ user.email }}</a>
</li>

Vamos ver agora o ciclo de vida de um Middleware dentro do Django.

Ciclo de vida de um Middleware no Django

Um middleware é um método callable (que tem implementa o método __call__()).

Esse método recebe uma requisição e retorna uma resposta, assim como uma View, podendo ser escrito como função ou como Classe.

Um exemplo de middleware escrito como função é:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def middleware_simples(get_response):
    # Código de inicialização do Middleware
    def middleware(request):
        # Aqui vai o código a ser executado antes 
        # da View e de outros middlewares
        # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        
        response = get_response(request)

        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        # Aqui vai o código a ser executado 
        # para cada resposta após a View 
        
        return response

    return middleware

E como Classe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MiddlewareSimples:
    def __init__(self, get_response):
        self.get_response = get_response
        # Código de inicialização do Middleware

    def __call__(self, request):
        # Aqui vai o código a ser executado antes 
        # da View e de outros middlewares
        # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        
        response = self.get_response(request)

        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        # Aqui vai o código a ser executado 
        # para cada resposta após a View         

        return response

Como cada Middleware é executado de maneira encadeada, do topo da configuração MIDDLEWARE (do settings.py) para o fim, a saída de um é a entrada do próximo.

O método get_response() pode ser a própria View, caso ela seja a última configurada no MIDDLEWARE do settings.py, ou o próximo middleware da cadeia.

Utilizando a construção do middleware via Classe, nós temos três métodos importantes, que veremos em seguida!

Está curtindo esse conteúdo? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

O método process_view

Assinatura: process_view(request, func, args, kwargs)

Esse método é chamado logo antes do Django executar a View que vai processar a requisição e possui os seguintes parâmetros:

  • request é o objeto HttpRequest.
  • func é a própria view que o Django está para chamar ao final da cadeia de middlewares.
  • args é a lista de parâmetros posicionais que serão passados à view.
  • kwargs é o dict contendo os argumentos nomeados (keyword arguments) que serão passados à view.

Esse método deve retornar None ou um objeto HttpResponse:

  • Caso retorne None, o Django entenderá que deve continuar a cadeia de Middlewares.
  • Caso retorne HttpResponse, o Django entenderá que a resposta está pronta para ser enviada de volta e não vai se preocupar em chamar o resto da cadeia de Middlewares, nem a view que iria processar a requisição.

O método process_exception

Assinatura: process_exception(request, exception)

Esse método é chamada quando uma view lança uma exceção e deve retornar ou None ou HttpResponse. Caso retorne um objeto HttpResponse, o Django irá aplicar o middleware de resposta e o de template, retornando a requisição ao browser.

  • request é o objeto HttpRequest
  • exception é a exceção propriamente dita lançada pela view (Exception).

O método process_template_response

Assinatura: process_template_response(request, response)

Esse método é chamado logo após a view ter terminado sua execução, caso a resposta tenha uma chamada ao método render() indicando que a reposta possui um template.

Possui os seguintes parâmetros:

  • request é um objeto HttpRequest.
  • response é o objeto TemplateResponse retornado pela view ou por outro middleware.

Agora vamos criar um middleware um pouco mais complexo para exemplificar o que foi dito aqui!

Ah, antes de seguir! Está curtindo esse conteúdo? Que tal levá-lo pra onde quiser?

Então já baixe nosso ebook GRÁTIS de Desenvolvimento Web com Python e Django!

:point_down: :point_down: :point_down:

Ebook GRÁTIS

DESENVOLVIMENTO WEB COM PYTHON E DJANGO

Capa Ebook Desenvolvimento Web com Python e Django

Conteúdo:

  • :point_right: Veja como modelar sua aplicação
  • :point_right: Utilize a robusta API de Acesso a Dados do Django
  • :point_right: Aprenda sobre Class Based Views
  • :point_right: Construa Middlewares próprios
  • :point_right: Desenvolva filtros e tags customizados para criar lindos templates
Baixe já!

Criando um Middleware no Django

Vamos supor que queremos um middleware que filtre requisições e só processe aquelas que venham de uma determinada lista de IP’s.

O que precisamos fazer é abrir o cabeçalho de todas as requisições que chegam no nosso servidor e verificar se o IP de origem bate com a nossa lista de IP’s.

Para isso, colocamos a lógica no método process_view, da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class FiltraIPMiddleware:    

  def __init__(self, get_response=None):
    self.get_response = get_response

  def __call__(self, request):
    response = self.get_response(request)

    return response

  def process_view(request, func, args, kwargs):
    # Lista de IPs autorizados
    ips_autorizados = ['127.0.0.1']

    # IP do usuário
    ip = request.META.get('REMOTE_ADDR')

    # Verifica se o IP do cliente está na lista de IPs autorizados
    if ip not in ips_autorizados:
      # Se usuário não autorizado > HTTP 403: Não Autorizado
      return HttpResponseForbidden("IP não autorizado")

    # Se for autorizado, não fazemos nada
    return None

Depois disso, precisamos registrar nosso middleware no arquivo de configurações settings.py (na configuração MIDDLEWARE):

1
2
3
4
5
6
7
8
9
10
11
12
13
MIDDLEWARE = [
  # Middlewares do próprio Django
  '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',

  # Nosso Middleware
  'helloworld.middlewares.FiltraIPMiddleware',
]

Agora, podemos testar seu funcionamento alterando a lista ips_autorizados:

  • Coloque ips_autorizados = ['127.0.0.1'] e tente acessar alguma URL da nossa aplicação: devemos conseguir acessar normalmente nossa aplicação, pois como estamos executando o servidor localmente, nosso IP será 127.0.0.1 e, portanto, passaremos no teste.
  • Coloque ips_autorizados = [] e tente acessar alguma URL da nossa aplicação: deve aparecer a mensagem de “IP não autorizado”, pois nosso IP (127.0.0.1) não está autorizado a acessar o servidor.

:wave: Ei, você aí! Quer se sentir realmente capaz ao desenvolver Aplicações Web com Django? Então clique no link abaixo e dê o próximo passo agora mesmo!

Jornada Django

A Jornada Django foi pensada em quem já sabe Python e quer dar o próximo passo. Aqui você vai dominar o Desenvolvimento Web com o poderoso Django.

Vinícius Ramos
Vinícius Ramos 🇺🇸 Senior Software Engineer 🇧🇷 Fundador
Conhecer detalhes
Check
Suporte a dúvidas
Check
Certificado de Conclusão
Check
Comunidade de Alunos
Check
Cursos gratuitos de HTML
Check
Cursos gratuitos de CSS
Check
Cursos gratuitos de Javascript

Conclusão

Nesse post vimos como é simples criar Middlewares no Django.

Vimos como podemos adicionar tratamento prévio ao processamento de requisições e posterior ao processamento de respostas.

Seus casos de uso são bem específicos, contudo é bom saber que temos essa possibilidade!

É isso dev, nos vemos na próxima! :wink:

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.