O Django é um dos frameworks web mais maduros no ecossistema Python, conhecido por sua robustez e simplicidade. No entanto, até recentemente, ele tinha uma característica que o fazia parecer um pouco… tradicional: tudo era síncrono. Isso significa que cada requisição e resposta eram tratadas de forma linear, uma de cada vez.
Não que isso seja um problema em si, mas quando você começa a lidar com operações que demoram (como consultas ao banco de dados ou chamadas para APIs externas), você se vê preso a esperas desnecessárias, e ninguém gosta de ficar parado esperando, certo?
Então, quando o Django finalmente trouxe suporte para views assíncronas, os desenvolvedores puderam comemorar (ou pelo menos, respirar aliviados). Agora, podemos lidar com I/O de forma assíncrona e não ficamos mais à mercê de uma conexão lenta ou de consultas demoradas.
Mas antes de começarmos a falar no como, é importante entender o porquê.
Por que usar views assíncronas? Bom, basicamente, elas nos permitem lidar com múltiplas requisições simultaneamente, sem bloquear o servidor, melhorando o desempenho da aplicação, especialmente quando estamos lidando com operações I/O intensivas.
Neste artigo, vamos explorar como implementar views assíncronas no Django, os prós e contras dessa abordagem e as melhores práticas para usar o async da forma correta.
Por que o Django demorou para adotar o async?
Se você está por dentro das tendências em desenvolvimento web, sabe que frameworks como Node.js já vêm lidando com programação assíncrona há bastante tempo. Então, por que o Django demorou tanto para adotar esse modelo?
A resposta curta: compatibilidade e complexidade. O Django foi construído com um modelo de programação síncrono em mente, o que significa que grande parte de sua arquitetura e de seus componentes foi desenvolvida assumindo que tudo seria tratado de forma linear. Migrar para async não é tão simples quanto mudar algumas linhas de código. Requer uma reformulação da infraestrutura subjacente para garantir que tudo funcione corretamente.
Outro fator importante é que muitas bibliotecas que o Django depende, como o ORM (a camada de acesso ao banco de dados), foram projetadas para serem síncronas. Mudar isso envolve mexer em várias engrenagens, sem quebrar a compatibilidade com o código legado.
No entanto, com o surgimento da interface ASGI (Asynchronous Server Gateway Interface), o Django passou a oferecer suporte nativo para operações assíncronas a partir da versão 3.1, permitindo que as views, middlewares e até mesmo servidores HTTP fossem adaptados para o modelo async.
Agora que o Django entrou no mundo async, podemos finalmente aproveitar os benefícios de melhor desempenho, maior eficiência em I/O e resposta mais rápida às requisições, especialmente em cenários que exigem chamadas externas ou operações que podem demorar mais do que gostaríamos.
Criando uma View Assíncrona
Agora vamos ao que interessa: código. Primeiro, vejamos um exemplo de uma view síncrona simples, para servir como comparação.
Exemplo de View Síncrona
from django.http import JsonResponse
def minha_view_sincrona(request):
# Simulando uma consulta ao banco de dados
dados = {"mensagem": "Isso é uma view síncrona!"}
return JsonResponse(dados)
PythonEssa é uma view comum, que você provavelmente já está acostumado a ver. Ela recebe a requisição, faz alguma operação (nesse caso, algo simples) e retorna uma resposta. No entanto, se essa view precisasse lidar com uma consulta ao banco de dados ou com uma chamada externa, você poderia acabar com um bloqueio, enquanto o servidor espera que a operação termine.
Exemplo de View Assíncrona
Agora, veja como ficaria uma versão assíncrona da mesma view:
from django.http import JsonResponse
import asyncio
async def minha_view_assincrona(request):
# Simulando uma operação assíncrona (como uma chamada a API)
await asyncio.sleep(2) # Simulando uma espera de 2 segundos
dados = {"mensagem": "Isso é uma view assíncrona!"}
return JsonResponse(dados)
PythonA principal diferença aqui é o uso do async
e do await
. Essa view está agora preparada para lidar com operações de forma não bloqueante. O await asyncio.sleep(2)
simula uma operação que leva tempo para ser concluída, mas a grande sacada é que, enquanto isso acontece, o servidor pode continuar respondendo a outras requisições.

Claro que você não vai usar sleep
em produção (a não ser que realmente goste de ver usuários esperando), mas imagine que essa espera fosse, por exemplo, uma chamada a uma API externa ou a consulta a um serviço de terceiros. A mágica aqui é que você pode lidar com múltiplas requisições de forma eficiente, sem que cada uma fique esperando pela outra.
Consultas ao Banco de Dados com Views Assíncronas
Agora, você deve estar se perguntando: “E o banco de dados? Como faço para usar uma view assíncrona com ele?” Boa pergunta! A resposta curta é que o ORM do Django ainda é síncrono. Portanto, se você fizer consultas diretamente com o ORM dentro de uma view assíncrona, o código vai funcionar, mas perderá os benefícios do async, pois a consulta ao banco de dados será bloqueante.
A solução é usar a função sync_to_async
, que permite “envolver” funções síncronas e executá-las de forma assíncrona.
Exemplo com Banco de Dados
Vamos criar um exemplo em que usamos uma view assíncrona que interage com o banco de dados:
from django.http import JsonResponse
from django.contrib.auth.models import User
from asgiref.sync import sync_to_async
async def minha_view_com_banco(request):
# Consultando usuários de forma assíncrona
usuarios = await sync_to_async(User.objects.all)()
dados = [{"id": usuario.id, "username": usuario.username} for usuario in usuarios]
return JsonResponse(dados, safe=False)
PythonAqui, o sync_to_async está sendo usado para transformar a consulta ao banco de dados (que é síncrona) em algo que pode ser aguardado dentro de uma view assíncrona. Isso significa que você ainda pode se beneficiar de outras operações assíncronas, como chamadas para APIs externas, enquanto espera que o banco de dados retorne seus resultados.
Integrando Async com Outras Funcionalidades do Django
Quando você começa a adotar o async, surge a necessidade de integrar essas views com o restante da aplicação, como middleware e sistemas de autenticação. A boa notícia é que o Django também oferece suporte para middleware assíncrono.
Middleware Assíncrono
Assim como as views, os middlewares no Django também podem ser assíncronos. Isso permite que você crie middlewares que não bloqueiem o fluxo da aplicação enquanto fazem alguma tarefa que leva tempo, como log de requisições ou verificações de autenticação.
Aqui está um exemplo de um middleware assíncrono:
class MeuMiddlewareAssincrono:
async def __init__(self, get_response):
self.get_response = get_response
async def __call__(self, request):
# Alguma lógica antes de processar a view
response = await self.get_response(request)
# Alguma lógica após processar a view
return response
PythonEsse middleware pode ser incluído no pipeline de middlewares, da mesma forma que os síncronos, no arquivo settings.py
.
Prós e Contras de Usar Views Assíncronas no Django
Agora que já vimos como implementar views assíncronas, é hora de discutir os benefícios e desafios desse modelo.
Prós:
- Melhor desempenho: Em operações I/O intensivas, como chamadas para APIs externas ou grandes operações de rede, views assíncronas podem lidar com múltiplas requisições de forma eficiente.
- Maior escalabilidade: Em sistemas com alto volume de tráfego, o async permite que o servidor processe várias requisições simultaneamente, sem bloqueios desnecessários.
Contras:
- Compatibilidade limitada: Nem todas as bibliotecas do ecossistema Django foram adaptadas para async. Isso pode levar a bugs ou comportamentos inesperados se você misturar async com código síncrono de forma errada.
- Complexidade: Programação assíncrona pode ser mais difícil de depurar e testar, especialmente quando se trata de erros de concorrência e condições de corrida.
- ORM ainda síncrono: O ORM do Django ainda é síncrono, o que significa que você precisa usar o
sync_to_async
para trabalhar com bancos de dados, o que pode limitar os ganhos de desempenho em certas situações.
Melhores Práticas para Usar Async no Django
Agora que você tem uma boa base sobre como usar views assíncronas no Django, aqui estão algumas melhores práticas para garantir que você está usando async de forma eficiente:
- Use async apenas onde for necessário: Não transforme todas as suas views em assíncronas. Use async principalmente para operações que envolvem I/O ou processos longos que podem ser executados em paralelo.
- Cuidado com o uso de bibliotecas: Verifique se as bibliotecas que você está usando são compatíveis com async, especialmente quando estiver lidando com operações críticas, como manipulação de arquivos ou conexões de rede.
- Teste suas views assíncronas: A programação assíncrona pode introduzir problemas difíceis de rastrear, como condições de corrida. Certifique-se de testar bem suas views assíncronas e garantir que elas estão se comportando conforme o esperado.
- Combine sync e async com cuidado: Use
sync_to_async
para garantir que as operações síncronas não bloqueiem o restante da aplicação, mas seja cauteloso para não sobrecarregar o sistema com muitas transições entre os dois modelos.
Conclusão
As views assíncronas no Django abriram novas possibilidades para melhorar o desempenho de aplicações web, especialmente em cenários que envolvem operações de I/O intensivas. Embora nem todo o ecossistema Django esteja completamente preparado para o async, já é possível se beneficiar desse modelo em diversas partes da aplicação.
Ao usar async, é importante manter o equilíbrio: use onde for necessário e evite sobrecarregar o código com async desnecessário. A programação assíncrona oferece grandes vantagens em termos de desempenho e escalabilidade, mas traz consigo desafios de compatibilidade e complexidade que precisam ser considerados.
E claro, como toda nova tecnologia, async no Django ainda está evoluindo. Com o tempo, podemos esperar melhorias no suporte a operações assíncronas, especialmente no que diz respeito ao ORM e às bibliotecas externas.
Agora que você tem uma boa noção de como implementar views assíncronas no Django, é hora de colocar as mãos na massa. Afinal, ninguém merece ficar esperando enquanto a água (ou a consulta ao banco) ferve.