Django: O que É e Como Funciona | Python Brasil
Guia completo do Django: framework web Python com ORM, admin, autenticação e muito mais. Exemplos práticos de queries, views e deploy.
O que é Django?
O Django é um framework web de alto nível escrito em Python que permite o desenvolvimento rápido e limpo de aplicações web. Ele segue o princípio “batteries included” — ou seja, já vem com tudo que você precisa para construir uma aplicação completa, sem depender de dezenas de bibliotecas externas.
O lema do Django é “The web framework for perfectionists with deadlines” (o framework web para perfeccionistas com prazos), e essa frase resume bem sua proposta: produtividade sem abrir mão da qualidade.
História e Origem
O Django nasceu em 2003 na redação do jornal Lawrence Journal-World, em Lawrence, Kansas (EUA). Os desenvolvedores Adrian Holovaty e Simon Willison precisavam criar e manter sistemas de notícias com rapidez, e construíram um framework interno para isso. Em julho de 2005, o Django foi lançado como projeto de código aberto.
O nome é uma homenagem ao guitarrista de jazz Django Reinhardt. Em 2008, foi fundada a Django Software Foundation (DSF) para gerir o projeto. Hoje o Django está na versão 5.x e é mantido por centenas de colaboradores ao redor do mundo.
Empresas como Instagram, Pinterest, Mozilla, Disqus e até a NASA usam Django em produção, o que prova sua capacidade de escalar para aplicações de grande porte.
Arquitetura MTV
O Django utiliza a arquitetura MTV (Model-Template-View), uma variação do padrão MVC:
- Model: define a estrutura dos dados e a interação com o banco de dados via ORM
- Template: cuida da apresentação (HTML), com uma linguagem de templates própria
- View: contém a lógica de negócio e conecta models com templates
O ORM do Django
O ORM (Object-Relational Mapper) do Django é um dos seus pontos mais fortes. Ele permite interagir com o banco de dados usando Python puro, sem escrever SQL manualmente.
# models.py
from django.db import models
class Categoria(models.Model):
nome = models.CharField(max_length=100)
def __str__(self):
return self.nome
class Artigo(models.Model):
titulo = models.CharField(max_length=200)
conteudo = models.TextField()
publicado_em = models.DateTimeField(auto_now_add=True)
atualizado_em = models.DateTimeField(auto_now=True)
publicado = models.BooleanField(default=False)
visualizacoes = models.PositiveIntegerField(default=0)
categoria = models.ForeignKey(
Categoria,
on_delete=models.SET_NULL,
null=True,
related_name="artigos"
)
class Meta:
ordering = ["-publicado_em"]
def __str__(self):
return self.titulo
Queries e Filtros
from myapp.models import Artigo
from django.db.models import Count, Avg, Q
from django.utils import timezone
# Buscar todos os artigos publicados
artigos = Artigo.objects.filter(publicado=True)
# Filtros combinados com Q (OR)
resultado = Artigo.objects.filter(
Q(titulo__icontains="python") | Q(conteudo__icontains="python")
)
# Ordenação e slice (paginação manual)
recentes = Artigo.objects.filter(publicado=True).order_by("-publicado_em")[:10]
# Aggregations
from django.db.models import Count
stats = Artigo.objects.aggregate(
total=Count("id"),
media_views=Avg("visualizacoes")
)
# {"total": 120, "media_views": 340.5}
# Annotate — conta artigos por categoria
categorias = Categoria.objects.annotate(
num_artigos=Count("artigos")
).order_by("-num_artigos")
# select_related — evita o problema N+1
artigos = Artigo.objects.select_related("categoria").filter(publicado=True)
for artigo in artigos:
print(artigo.categoria.nome) # sem consultas extras ao banco
O Admin do Django
O painel administrativo do Django é gerado automaticamente a partir dos seus models. Com poucas linhas de código você tem um CRUD completo, pesquisa, filtros e exportação.
# admin.py
from django.contrib import admin
from .models import Artigo, Categoria
@admin.register(Artigo)
class ArtigoAdmin(admin.ModelAdmin):
list_display = ["titulo", "categoria", "publicado", "visualizacoes", "publicado_em"]
list_filter = ["publicado", "categoria"]
search_fields = ["titulo", "conteudo"]
list_editable = ["publicado"]
date_hierarchy = "publicado_em"
readonly_fields = ["publicado_em", "atualizado_em"]
actions = ["publicar_artigos"]
def publicar_artigos(self, request, queryset):
queryset.update(publicado=True)
self.message_user(request, "Artigos publicados com sucesso!")
publicar_artigos.short_description = "Publicar artigos selecionados"
admin.site.register(Categoria)
Acesse /admin/ com as credenciais de superusuário e você terá um backoffice completo sem escrever uma linha de HTML.
URLs e Views
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("artigos/", views.ListaArtigos.as_view(), name="lista-artigos"),
path("artigos/<int:pk>/", views.DetalheArtigo.as_view(), name="detalhe-artigo"),
path("artigos/<int:pk>/editar/", views.EditarArtigo.as_view(), name="editar-artigo"),
]
# views.py
from django.views.generic import ListView, DetailView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Artigo
class ListaArtigos(ListView):
model = Artigo
template_name = "artigos/lista.html"
context_object_name = "artigos"
paginate_by = 10
def get_queryset(self):
return Artigo.objects.filter(publicado=True).select_related("categoria")
class DetalheArtigo(DetailView):
model = Artigo
template_name = "artigos/detalhe.html"
class EditarArtigo(LoginRequiredMixin, UpdateView):
model = Artigo
fields = ["titulo", "conteudo", "publicado"]
template_name = "artigos/editar.html"
Middleware
O middleware do Django é uma camada de processamento que envolve cada requisição e resposta. O Django já inclui middlewares essenciais:
SecurityMiddleware: adiciona headers de segurança (HSTS, XSS protection)SessionMiddleware: gerencia sessões de usuárioCsrfViewMiddleware: proteção contra ataques CSRFAuthenticationMiddleware: vincula usuários à requisição
Você também pode criar middleware customizado:
# middleware.py
import time
import logging
logger = logging.getLogger(__name__)
class TempoRequisicaoMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
inicio = time.time()
response = self.get_response(request)
duracao = time.time() - inicio
logger.info(f"{request.method} {request.path} - {duracao:.3f}s")
return response
Django REST Framework
Para APIs REST, o Django REST Framework (DRF) é a extensão mais usada. Ele adiciona serializers, viewsets e autenticação para APIs.
# serializers.py
from rest_framework import serializers
from .models import Artigo
class ArtigoSerializer(serializers.ModelSerializer):
class Meta:
model = Artigo
fields = ["id", "titulo", "conteudo", "publicado_em", "categoria"]
read_only_fields = ["publicado_em"]
# views.py (API)
from rest_framework import viewsets, permissions
class ArtigoViewSet(viewsets.ModelViewSet):
queryset = Artigo.objects.filter(publicado=True)
serializer_class = ArtigoSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
filterset_fields = ["categoria"]
search_fields = ["titulo", "conteudo"]
ordering_fields = ["publicado_em", "visualizacoes"]
Segurança
O Django protege sua aplicação por padrão contra os ataques mais comuns:
- CSRF: token automático em formulários POST
- XSS: templates escapam HTML automaticamente
- SQL Injection: o ORM usa queries parametrizadas
- Clickjacking: header
X-Frame-Optionsconfigurado - Senhas: armazenadas com hash PBKDF2 por padrão
Deploy com Gunicorn e Nginx
# Instalar dependências
pip install gunicorn
# Iniciar o servidor WSGI
gunicorn meusite.wsgi:application --workers 4 --bind 0.0.0.0:8000
Exemplo de configuração do Nginx:
server {
listen 80;
server_name meusite.com.br;
location /static/ {
alias /var/www/meusite/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Quando Escolher Django
Django é a escolha certa quando você precisa de:
- Um sistema completo com autenticação, admin e ORM prontos
- Velocidade de desenvolvimento em projetos maiores
- Um painel administrativo sem esforço extra
- Aplicações como e-commerce, CMS, portais e SaaS
Se o projeto for uma API simples ou microsserviço, considere FastAPI. Se precisar de flexibilidade máxima com menos opinião, considere Flask.
Erros Comuns
- Problema N+1: usar
select_relatedeprefetch_relatedpara evitar múltiplas queries desnecessárias - Não usar
defer()ouonly(): buscar apenas os campos necessários em listas grandes - Esquecer de rodar
collectstatic: arquivos estáticos não aparecem em produção - DEBUG=True em produção: expõe informações sensíveis do sistema
Boas Práticas
- Mantenha o
settings.pyseparado por ambiente (development, production) - Use variáveis de ambiente para credenciais (biblioteca
python-decoupleoudjango-environ) - Escreva testes com
django.test.TestCase - Use
select_relatedeprefetch_relatedpara otimizar queries - Ative o
django-debug-toolbardurante o desenvolvimento