O que é o Django?
Conheça o framework web Python que alimenta Instagram, Pinterest e milhares de aplicações no mundo todo.
Definição simples
Django é um framework web de alto nível escrito em Python que incentiva o desenvolvimento rápido e design limpo e pragmático. Ele foi criado para que desenvolvedores possam construir aplicações web complexas sem reinventar a roda.
O slogan oficial é: "The web framework for perfectionists with deadlines" — o framework web para perfeccionistas com prazo. Isso resume bem a filosofia: Django é opinativo (tem um jeito certo de fazer as coisas) mas extremamente produtivo. Você passa o tempo construindo features, não configurando infraestrutura básica.
Django foi criado em 2003 por Adrian Holovaty e Simon Willison para o jornal Lawrence Journal-World, e é mantido pela Django Software Foundation. Está na versão 5.x e tem compatibilidade garantida de longo prazo nas versões LTS.
Por que usar Django?
- Batteries included: traz ORM, autenticação, admin, sistema de migrations, cache, formulários e muito mais nativamente
- Segurança: protege contra CSRF, XSS, SQL Injection e clickjacking por padrão
- Escalável: usado pelo Instagram com bilhões de usuários
- Comunidade enorme: milhares de pacotes (PyPI) e anos de documentação de alta qualidade
- ORM poderoso: trabalhe com o banco de dados usando Python puro, sem escrever SQL na maioria dos casos
- Admin automático: painel de gerenciamento gerado automaticamente a partir dos seus models
- Documentação excelente: a documentação oficial do Django é referência na indústria
O padrão MTV
Django usa o padrão MTV (Model–Template–View), similar ao MVC tradicional:
- Model: define a estrutura dos dados e se comunica com o banco de dados via ORM
- Template: é o HTML que o usuário vê (em APIs REST, é substituído por JSON)
- View: contém a lógica de negócio, processa requisições HTTP e retorna respostas
O fluxo de uma requisição Django funciona assim: o usuário acessa uma URL → o Django consulta ourls.py para encontrar a view responsável → a view processa a lógica (consulta models, valida dados) → retorna uma resposta (HTML via template ou JSON via DRF).
Estrutura de um projeto Django
meu_projeto/
├── manage.py # CLI do Django (runserver, migrate, etc.)
├── requirements.txt # dependências Python
├── .env # variáveis de ambiente (nunca comite!)
├── meu_projeto/ # pacote de configurações
│ ├── __init__.py
│ ├── settings.py # todas as configurações
│ ├── urls.py # roteamento principal
│ ├── wsgi.py # servidor WSGI (produção)
│ └── asgi.py # servidor ASGI (Channels/async)
└── blog/ # um app Django
├── __init__.py
├── admin.py # configuração do admin
├── apps.py # configuração do app
├── models.py # seus models (banco de dados)
├── views.py # lógica das páginas
├── urls.py # rotas do app
├── serializers.py # para DRF (APIs)
├── tests.py # testes
└── migrations/ # migrations geradas pelo Django
└── 0001_initial.pyCada app Django é um módulo independente que encapsula uma funcionalidade. Um projeto pode ter múltiplos apps: users, blog, payments, etc. A boa prática é manter cada app focado em uma responsabilidade.
Exemplo de Model
Criar uma tabela no banco de dados é simplesmente criar uma classe Python que herda de models.Model. O Django cuida de toda a lógica SQL por baixo:
from django.db import models
from django.contrib.auth import get_user_model
from django.utils.text import slugify
User = get_user_model()
class Categoria(models.Model):
nome = models.CharField(max_length=100, unique=True)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.nome)
super().save(*args, **kwargs)
def __str__(self):
return self.nome
class Post(models.Model):
titulo = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
conteudo = models.TextField()
resumo = models.CharField(max_length=300, blank=True)
autor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
categoria = models.ForeignKey(Categoria, on_delete=models.SET_NULL, null=True, blank=True)
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)
class Meta:
ordering = ['-publicado_em']
verbose_name = 'Post'
verbose_name_plural = 'Posts'
def __str__(self):
return self.titulo
@property
def tempo_leitura(self):
palavras = len(self.conteudo.split())
return max(1, round(palavras / 200)) # 200 palavras/minutoViews e URLs
As views no Django processam requisições e retornam respostas. Existem duas formas principais:function-based views (FBV) e class-based views (CBV).
# views.py — function-based view (simples e direta)
from django.shortcuts import render, get_object_or_404
from .models import Post
def lista_posts(request):
posts = Post.objects.filter(publicado=True).select_related('autor', 'categoria')
return render(request, 'blog/lista.html', {'posts': posts})
def detalhe_post(request, slug):
post = get_object_or_404(Post, slug=slug, publicado=True)
post.visualizacoes += 1
post.save(update_fields=['visualizacoes'])
return render(request, 'blog/detalhe.html', {'post': post})
# views.py — class-based view (mais recursos, menos código para CRUD)
from django.views.generic import ListView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
class PostListView(ListView):
model = Post
template_name = 'blog/lista.html'
context_object_name = 'posts'
paginate_by = 10
def get_queryset(self):
return Post.objects.filter(publicado=True).select_related('autor')# urls.py do app blog
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.PostListView.as_view(), name='lista'),
path('<slug:slug>/', views.detalhe_post, name='detalhe'),
]
# urls.py principal (meu_projeto/urls.py)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
path('api/', include('blog.api_urls')), # para DRF
]ORM do Django — Consultando o banco
O ORM do Django permite consultar o banco de dados com Python puro. Aqui estão as operações mais comuns:
# Buscar todos os posts publicados
posts = Post.objects.filter(publicado=True)
# Buscar um único post (levanta Post.DoesNotExist se não achar)
post = Post.objects.get(slug='meu-post')
# Buscar ou 404 (atalho para views)
post = get_object_or_404(Post, slug='meu-post', publicado=True)
# Filtros avançados
posts_recentes = Post.objects.filter(
publicado=True,
publicado_em__gte=timezone.now() - timedelta(days=30)
).order_by('-publicado_em')
# Select relacionados (evita N+1 queries)
posts = Post.objects.select_related('autor', 'categoria').prefetch_related('tags')
# Agregar dados
from django.db.models import Count, Avg
stats = Post.objects.aggregate(
total=Count('id'),
media_visualizacoes=Avg('visualizacoes')
)
# Anotar queryset
posts = Post.objects.annotate(
num_comentarios=Count('comentarios')
).order_by('-num_comentarios')
# Criar
post = Post.objects.create(
titulo='Novo Post',
slug='novo-post',
conteudo='Conteúdo...',
autor=request.user,
publicado=True,
)
# Atualizar em massa
Post.objects.filter(autor=user).update(publicado=False)
# Deletar
Post.objects.filter(publicado=False, publicado_em__lt=cutoff).delete()Django Admin
Um dos recursos mais amados do Django é o Admin automático. Com poucas linhas, você tem um painel completo de gerenciamento de dados:
from django.contrib import admin
from .models import Post, Categoria
@admin.register(Categoria)
class CategoriaAdmin(admin.ModelAdmin):
list_display = ['nome', 'slug']
prepopulated_fields = {'slug': ('nome',)}
search_fields = ['nome']
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ['titulo', 'autor', 'categoria', 'publicado', 'publicado_em', 'visualizacoes']
list_filter = ['publicado', 'categoria', 'publicado_em']
search_fields = ['titulo', 'conteudo', 'autor__username']
prepopulated_fields = {'slug': ('titulo',)}
date_hierarchy = 'publicado_em'
ordering = ['-publicado_em']
raw_id_fields = ['autor']
# Ações personalizadas
actions = ['publicar_posts', 'despublicar_posts']
@admin.action(description='Publicar posts selecionados')
def publicar_posts(self, request, queryset):
queryset.update(publicado=True)
@admin.action(description='Despublicar posts selecionados')
def despublicar_posts(self, request, queryset):
queryset.update(publicado=False)Migrations — versionando o banco de dados
O sistema de migrations do Django rastreia todas as mudanças nos seus models e as aplica ao banco de dados de forma controlada. É como um sistema de controle de versão para o schema do banco.
# Após modificar um model, gere a migration:
python manage.py makemigrations
# Veja o SQL que será executado (sem aplicar):
python manage.py sqlmigrate blog 0001
# Aplique as migrations ao banco:
python manage.py migrate
# Ver status das migrations:
python manage.py showmigrations
# Reverter uma migration (cuidado!):
python manage.py migrate blog 0001 # volta para a migration 0001As migrations são arquivos Python que ficam no diretório migrations/ de cada app. Sempre comite as migrations junto com as mudanças nos models — elas fazem parte do código.
Como criar um projeto Django do zero
- Crie um ambiente virtual:
python -m venv venv && source venv/bin/activate - Instale as dependências:
pip install django djangorestframework django-allauth dj-rest-auth - Crie o projeto:
django-admin startproject meu_projeto . - Crie um app:
python manage.py startapp blog - Configure o settings.py (banco, apps instalados, etc.)
- Rode as migrations iniciais:
python manage.py migrate - Crie um superusuário:
python manage.py createsuperuser - Rode o servidor:
python manage.py runserver
# settings.py — configurações essenciais para produção
import environ
env = environ.Env()
environ.Env.read_env()
SECRET_KEY = env('SECRET_KEY')
DEBUG = env.bool('DEBUG', default=False)
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
DATABASES = {
'default': env.db('DATABASE_URL') # ex: postgresql://user:pass@host/db
}
# Arquivos estáticos
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# Internacionalização
LANGUAGE_CODE = 'pt-br'
TIME_ZONE = 'America/Sao_Paulo'
USE_I18N = True
USE_TZ = TrueSignals — reagindo a eventos do Django
Signals permitem que partes desacopladas da aplicação sejam notificadas quando certas ações ocorrem, como salvar ou deletar um objeto:
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from .models import Post, Perfil
User = get_user_model()
# Criar perfil automaticamente quando um usuário é criado
@receiver(post_save, sender=User)
def criar_perfil(sender, instance, created, **kwargs):
if created:
Perfil.objects.create(usuario=instance)
# Invalidar cache quando um post é salvo
@receiver(post_save, sender=Post)
def invalidar_cache_post(sender, instance, **kwargs):
from django.core.cache import cache
cache.delete(f'post:{instance.slug}')
cache.delete('posts:lista')
# Conectar signals no apps.py do app
# blog/apps.py
class BlogConfig(AppConfig):
name = 'blog'
def ready(self):
import blog.signals # noqaPerguntas Frequentes
Django é só para APIs ou serve para sites completos?
Django serve para tudo: sites completos com templates HTML (Django Templates), APIs puras com Django REST Framework, e até aplicações em tempo real com Django Channels. É muito flexível.
Devo aprender Flask ou Django?
Para projetos sérios e que crescem, Django é a melhor escolha. Flask é mais simples e minimalista, ótimo para microserviços ou APIs pequenas. Nos tutoriais do canal, focamos em Django por ser mais completo para aplicações reais.
Django funciona bem com banco de dados PostgreSQL?
Sim, PostgreSQL é a combinação mais recomendada com Django em produção. O ORM do Django suporta nativamente PostgreSQL, MySQL, SQLite e Oracle. Com PostgreSQL você também tem acesso a campos especiais como JSONField, ArrayField e full-text search.
Preciso saber Python avançado para aprender Django?
Não precisa ser expert. Conhecimento intermediário de Python (funções, classes, módulos, decorators básicos) é suficiente para começar. O Django ensina boas práticas no processo.
Quais grandes sites usam Django?
Instagram, Pinterest, Disqus, Mozilla, National Geographic, Spotify (partes do backend) e muitos outros usam Django. É uma tecnologia testada em escala bilionária.
O que são as migrations do Django e por que são importantes?
Migrations são arquivos Python gerados automaticamente pelo Django que descrevem mudanças no schema do banco de dados. Elas permitem versionar o banco de dados junto com o código, fazer rollback e manter ambientes sincronizados. São essenciais para trabalho em equipe.
Como funciona o sistema de autenticação do Django?
Django vem com um sistema de autenticação completo: modelo User, login/logout, grupos, permissões e decorators como @login_required. Para autenticação social (Google, GitHub) ou APIs JWT, use o django-allauth com dj-rest-auth.
Qual a diferença entre Django e Django REST Framework?
Django é o framework base, completo para sites com templates HTML. O Django REST Framework (DRF) é uma biblioteca adicional que facilita a criação de APIs JSON. Para um backend que serve um frontend React ou mobile, você usa Django + DRF juntos.
Django suporta WebSockets e tempo real?
Sim, via Django Channels. É uma extensão oficial que adiciona suporte a WebSockets, permitindo aplicações em tempo real como chats, notificações ao vivo e dashboards. Usa ASGI em vez de WSGI.