W3docs

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

CamadaTermo DjangoResponsabilidade
DadosModelClasse Python que mapeia para uma tabela de banco de dados
ApresentaçãoTemplateArquivo HTML com marcadores {{ variable }}
LógicaViewFunçã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           # Windows

Apó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 django

Verifique a instalação:

python -m django --version

O 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 mysite

Isso 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 point

manage.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 blog

Registre-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 functions

Definindo 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 first

Tipos de campo principais usados aqui:

CampoFinalidade
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 migrate

Você 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... OK

Execute 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 createsuperuser

O 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 runserver

Faç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.html

blog/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 / FiltroO 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:30Encurta 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 runserver

Em 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 é:

  1. O navegador envia GET /
  2. O dispatcher de URLs do Django corresponde a '' e chama post_list
  3. post_list consulta Post.objects.all() (traduz para SELECT * FROM blog_post ORDER BY date_posted DESC)
  4. O Django renderiza post_list.html, inserindo os posts no template
  5. 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.py

Erros 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

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.

Was this page helpful?