Tutorial Django
Aprenda Django do zero: instale o framework, crie models, views, templates, execute migrations e lance uma aplicação web passo a passo.
Django é um framework web Python de alto nível que permite criar aplicações web seguras e escaláveis rapidamente. Ele segue o padrão arquitetural Model-Template-View (MTV) — parente próximo do MVC — e já vem com um ORM, interface de administração, roteamento de URLs, autenticação e muito mais embutidos. A filosofia "batteries-included" do Django significa que você gasta seu tempo na lógica da aplicação, e não montando infraestrutura.
Este tutorial percorre as etapas essenciais: instalar o Django dentro de um ambiente virtual, criar um projeto e um app, definir models, escrever views, construir templates, executar migrations de banco de dados e verificar tudo no navegador.
Por que usar Django
Batteries Included
O Django vem com painel de administração embutido, autenticação de usuários, tratamento de formulários, ORM, suporte a cache e utilitários de internacionalização. Não é necessário procurar pacotes de terceiros para cobrir esses recursos básicos.
Segurança por Padrão
O Django protege contra injeção de SQL usando consultas parametrizadas por meio do seu ORM. Ele também oferece proteção embutida contra Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF) e clickjacking. A chave secreta, o modo DEBUG e as configurações de ALLOWED_HOSTS reduzem ainda mais a superfície de ataque.
Escalabilidade
O Django alimenta sites de alto tráfego, incluindo Instagram e Disqus. Seu framework de cache integra-se com Memcached e Redis, e o ORM suporta connection pooling de banco de dados. É possível escalar verticalmente ou horizontalmente sem alterar o código da aplicação.
Grande Ecossistema
O índice de pacotes do Django lista milhares de apps de terceiros — REST APIs (djangorestframework), manipulação de imagens, gateways de pagamento e muito mais. A estabilidade do framework e o longo ciclo de lançamentos significam que esses pacotes são ativamente mantidos.
Como funciona o padrão MTV do Django
| Camada | Termo Django | Responsabilidade |
|---|---|---|
| Dados | Model | Classe Python que mapeia para uma tabela de banco de dados |
| Apresentação | Template | Arquivo HTML com marcadores {{ variable }} |
| Lógica | View | Função (ou classe) Python que lê dados e retorna uma resposta |
O dispatcher de URLs (urls.py) mapeia os caminhos de requisição recebidos para a view correta. A view consulta os models e passa os dados para um template. O HTML renderizado é retornado ao navegador.
Configurando um Ambiente Virtual
Sempre isole projetos Django em um ambiente virtual para que as dependências não conflitem entre projetos.
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
venv\Scripts\activate # WindowsApós a ativação, o prompt exibe (venv). Todo pip install a partir deste ponto afeta apenas este ambiente.
Instalando o Django
Com o ambiente virtual ativo, instale o Django usando o pip:
pip install djangoVerifique a instalação:
python -m django --versionO Django imprime uma string de versão como 5.1.4.
Criando um Projeto Django
Um projeto é o contêiner de nível superior para todo o seu site. Crie um com:
django-admin startproject mysite
cd mysiteIsso gera a seguinte estrutura:
mysite/
├── manage.py # Command-line utility for this project
└── mysite/
├── __init__.py
├── settings.py # Project configuration (database, installed apps, …)
├── urls.py # Root URL dispatcher
├── asgi.py # ASGI entry point
└── wsgi.py # WSGI entry pointmanage.py é sua principal ferramenta para executar comandos, como iniciar o servidor de desenvolvimento, criar migrations e criar um superusuário. A pasta interna mysite/ é o pacote Python do próprio projeto.
Criando um App Django
Um projeto pode conter múltiplos apps — módulos autocontidos, cada um responsável por uma área de funcionalidade. Crie um app de blog:
python manage.py startapp blogRegistre-o para que o Django possa encontrar seus models, templates e arquivos estáticos. Abra mysite/settings.py e adicione 'blog' ao INSTALLED_APPS:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # <-- add this line
]O diretório do app fica assim após a criação:
blog/
├── __init__.py
├── admin.py # Register models with the admin interface
├── apps.py # App configuration
├── migrations/ # Auto-generated migration files
│ └── __init__.py
├── models.py # Database models
├── tests.py
└── views.py # View functionsDefinindo Models
Um model é uma classe Python que herda de django.db.models.Model. Cada atributo de classe mapeia para uma coluna do banco de dados. O ORM do Django traduz seu código Python em SQL e cuida de todas as interações com o banco de dados.
Abra blog/models.py e defina um model Post:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-date_posted'] # Newest posts firstTipos de campo principais usados aqui:
| Campo | Finalidade |
|---|---|
CharField(max_length=N) | Texto curto com comprimento máximo |
TextField() | Texto de comprimento ilimitado |
ForeignKey(…, on_delete=CASCADE) | Relação many-to-one; exclui posts quando o autor é excluído |
DateTimeField(auto_now_add=True) | Definido uma vez quando o registro é criado |
DateTimeField(auto_now=True) | Atualizado toda vez que o registro é salvo |
O método __str__ controla como o objeto é exibido no painel de administração e no shell Python.
Executando Migrations
Após definir ou alterar models, é necessário criar e aplicar migrations — instruções versionadas que atualizam o esquema do banco de dados.
# Generate a new migration file from your model changes
python manage.py makemigrations
# Apply all pending migrations to the database
python manage.py migrateVocê verá uma saída como:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OKExecute migrate sempre que adicionar, remover ou modificar campos de model. Nunca edite arquivos de migration manualmente, a menos que compreenda totalmente o SQL deles.
Usando o Painel de Administração do Django
A interface de administração embutida permite criar, ler, atualizar e excluir registros pelo navegador — sem necessidade de interface personalizada. Registre o model Post em blog/admin.py:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date_posted')
list_filter = ('date_posted', 'author')
search_fields = ('title', 'content')Crie uma conta de superusuário para poder fazer login:
python manage.py createsuperuserO Django solicita nome de usuário, e-mail e senha. Em seguida, inicie o servidor de desenvolvimento e acesse http://127.0.0.1:8000/admin/:
python manage.py runserverFaça login com as credenciais do superusuário e você verá o model Posts listado na seção "Blog".
Escrevendo Views
Uma view é uma função (ou classe) Python que recebe uma requisição HTTP e retorna uma resposta HTTP. Abra blog/views.py:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
"""Display all published posts, newest first."""
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
"""Display a single post by primary key."""
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})get_object_or_404 é um atalho útil: ele busca o objeto no banco de dados ou retorna automaticamente uma resposta 404 se ele não existir. O terceiro argumento de render é um dicionário de contexto — suas chaves se tornam variáveis de template.
Criando Templates
Templates são arquivos HTML que contêm tags da Django Template Language (DTL). Crie a estrutura de diretórios:
blog/
└── templates/
└── blog/
├── base.html
├── post_list.html
└── post_detail.htmlblog/templates/blog/base.html — um layout compartilhado:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
<header><h1>My Blog</h1></header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
blog/templates/blog/post_list.html — a página de listagem:
{% extends "blog/base.html" %}
{% block title %}All Posts{% endblock %}
{% block content %}
{% for post in posts %}
<article>
<h2><a href="/blog/{{ post.pk }}/">{{ post.title }}</a></h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
{% empty %}
<p>No posts yet.</p>
{% endfor %}
{% endblock %}
blog/templates/blog/post_detail.html — a página de detalhe:
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h2>{{ post.title }}</h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<div>{{ post.content }}</div>
<a href="/">Back to all posts</a>
{% endblock %}
Principais recursos DTL usados acima:
| Tag / Filtro | O que faz |
|---|---|
{% extends "…" %} | Herda de um template base |
{% block name %} | Define uma seção substituível |
{{ variable }} | Exibe um valor (escapado automaticamente em HTML) |
{% for … %} / {% empty %} | Loop com fallback para listas vazias |
|date:"N j, Y" | Formata um valor de data e hora |
|truncatewords:30 | Encurta o texto para 30 palavras |
Configurando URLs
A configuração de URLs mapeia caminhos de requisição para funções de view.
blog/urls.py — crie este arquivo no diretório blog:
from django.urls import path
from . import views
app_name = 'blog' # Enables namespaced URL reversing
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]mysite/urls.py — inclua as URLs do app na raiz do projeto:
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('', include('blog.urls', namespace='blog_root')),
]O conversor de caminho <int:pk> captura um inteiro da URL e o passa como argumento de palavra-chave pk para post_detail.
Verificando o Fluxo Completo
Inicie o servidor de desenvolvimento:
python manage.py runserverEm seguida, abra http://127.0.0.1:8000/ no seu navegador. Se não houver posts ainda, o template exibe "No posts yet." Faça login em http://127.0.0.1:8000/admin/ e adicione um post. Atualize a página inicial — o post aparece imediatamente.
O ciclo de vida da requisição para a página inicial é:
- O navegador envia
GET / - O dispatcher de URLs do Django corresponde a
''e chamapost_list post_listconsultaPost.objects.all()(traduz paraSELECT * FROM blog_post ORDER BY date_posted DESC)- O Django renderiza
post_list.html, inserindo os posts no template - O HTML renderizado é retornado ao navegador
Guia de Consultas do ORM Django
O ORM permite construir consultas SQL usando cadeias de métodos Python. Compreender os lookups mais comuns economiza tempo significativo:
# All posts
Post.objects.all()
# Posts by a specific author
Post.objects.filter(author__username='alice')
# Posts containing a word in the title (case-insensitive)
Post.objects.filter(title__icontains='django')
# The five most recent posts
Post.objects.order_by('-date_posted')[:5]
# Count posts
Post.objects.count()
# Get one object (raises DoesNotExist if not found)
Post.objects.get(pk=1)
# Exclude posts by a specific author
Post.objects.exclude(author__username='alice')Cada uma dessas expressões gera uma consulta SQL apenas quando o queryset é avaliado (iterado, fatiado ou convertido em lista). Isso é chamado de avaliação preguiçosa e mantém as chamadas desnecessárias ao banco de dados no mínimo.
Resumo da Estrutura do Projeto
Após concluir este tutorial, a estrutura do projeto fica assim:
mysite/
├── manage.py
├── mysite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── blog/
├── admin.py
├── migrations/
│ └── 0001_initial.py
├── models.py
├── templates/
│ └── blog/
│ ├── base.html
│ ├── post_list.html
│ └── post_detail.html
├── urls.py
└── views.pyErros Comuns
Esquecer de registrar o app. Se 'blog' estiver ausente de INSTALLED_APPS, o Django não encontrará seus models ou templates e makemigrations não produzirá saída para esse app.
Pular migrate após makemigrations. Executar apenas makemigrations cria o arquivo de migration, mas não altera o banco de dados. Sempre execute migrate em seguida.
Erros de template não encontrado. O Django procura templates dentro do diretório templates/ de cada app. A subpasta extra blog/ dentro de templates/ (templates/blog/post_list.html) é uma convenção que evita colisões de nomes entre apps — não a omita.
DEBUG = True em produção. O servidor de desenvolvimento e DEBUG = True expõem tracebacks para qualquer pessoa. Defina DEBUG = False e configure ALLOWED_HOSTS antes de fazer o deploy.
Próximos Passos
- Módulos Python — entenda como o sistema de módulos do Python sustenta a estrutura de importação do Django.
- Python PIP — gerencie o Django e suas dependências.
- Ambientes Virtuais Python — mantenha cada projeto Django isolado.
- MySQL com Python — substitua o SQLite por um banco de dados pronto para produção.
- MongoDB com Python — use um backend NoSQL com Django.
A documentação oficial do Django em docs.djangoproject.com cobre class-based views, formulários, autenticação, REST APIs com Django REST Framework e deploy em produção — todos passos naturais depois que você estiver confortável com os conceitos básicos abordados aqui.