Voltar ao Glossario
Glossario Python

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ário
  • CsrfViewMiddleware: proteção contra ataques CSRF
  • AuthenticationMiddleware: 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-Options configurado
  • 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_related e prefetch_related para evitar múltiplas queries desnecessárias
  • Não usar defer() ou only(): 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.py separado por ambiente (development, production)
  • Use variáveis de ambiente para credenciais (biblioteca python-decouple ou django-environ)
  • Escreva testes com django.test.TestCase
  • Use select_related e prefetch_related para otimizar queries
  • Ative o django-debug-toolbar durante o desenvolvimento

Termos Relacionados

  • Flask - Microframework web alternativo
  • FastAPI - Framework moderno para APIs
  • API REST - Conceitos de APIs RESTful
  • Python - A linguagem base do Django