Capítulo 27
Django: introdução
4 min de leitura 721 palavras 1 gravura
Trabalhe numa cópia da pasta inicio/ desta etapa. Ela já abre ou executa com as instruções do README. Leia o código, mude uma coisa e anote sua previsão antes de recarregar. Compare com a referência na pasta da etapa. Se nada mudar, confira a extensão do arquivo, o arquivo salvo e o caminho aberto. Blocos adicionais do capítulo são experiências separadas; a pasta de referência contém o programa completo desta etapa.
O capítulo 26 mostrou que um servidor responde no seu computador. Agora o servidor da Biblioteca da Ribeira usa Django. A biblioteca é um acervo comunitário fictício no bairro da Ribeira, em Recife. Os títulos e as autorias são inventados.
Django é um conjunto de arquivos Python. Ele recebe um pedido do navegador e devolve uma página HTML. O esqueleto já está na pasta exemplos/27-django-introducao/. Você não cria o projeto do zero.
Ciclo desta etapa: leia, copie o comando, mude uma coisa, preveja, recarregue e confira. O servidor de estudo fica só em 127.0.0.1:8000.
O que você vai aprender
- Dizer o que o Django faz neste volume.
- Criar um ambiente virtual e instalar com
pip. - Rodar
migratee o servidor em127.0.0.1:8000. - Abrir a página inicial do esqueleto já pronto.
O que é Django
Um framework é uma estrutura pronta. Django organiza pastas, rotas, páginas e dados para você não inventar o servidor do zero.
Neste volume o projeto Python se chama ribeira. O aplicativo do catálogo se chama catalogo. O arquivo manage.py é o interruptor: com ele você instala tabelas, sobe o servidor e, mais tarde, roda testes.
O navegador pede http://127.0.0.1:8000/. O Django escolhe uma view (função que trata o pedido) e um template (arquivo HTML com lacunas). A resposta volta para a janela.

Ainda não há modelo de livro nesta pasta. Isso entra no capítulo 28. Hoje o objetivo é ver o esqueleto vivo.
Pare e experimente. Abra templates/inicio.html no editor. Troque só o texto do h1 para citar a Ribeira. Não recarregue ainda. Preveja o título novo. Depois o servidor vai mostrar essa mudança.
Ambiente virtual e pip
Um ambiente virtual é uma pasta Python só deste projeto. Os pacotes não se misturam com outros cursos.
No PowerShell, entre na pasta do exemplo e rode:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
venv cria .venv. O Activate.ps1 liga o ambiente: o prompt mostra (.venv). requirements.txt lista Django 5. O pip baixa e instala nessa pasta.
O arquivo de requisitos deste exemplo é só isto:
Django>=5.0,<6
Erro comum: instalar sem ativar o ambiente. O pip então grava no Python global. Se python -c "import django" falhar depois de ativar, volte e ative de novo.
migrate e o servidor local
migrate cria o arquivo SQLite db.sqlite3. SQLite é um banco em um arquivo, neste computador. Não há nuvem. Os dados são de estudo.
python manage.py migrate
python manage.py runserver 127.0.0.1:8000
Abra só http://127.0.0.1:8000/. Você deve ver o título da biblioteca e os links Livros e Admin. Encerre o servidor com Ctrl+C.
As rotas já estão no esqueleto:
from django.contrib import admin
from django.urls import path
from catalogo import views
urlpatterns = [
path("admin/", admin.site.urls),
path("", views.inicio),
path("livros/", views.livros),
]
A view da home renderiza o template:
from django.http import HttpResponse
from django.shortcuts import render
try:
from .models import Livro
except Exception:
Livro = None
def inicio(request):
return render(request, "inicio.html", {"fase": "local"})
def livros(request):
if Livro is None:
return render(request, "livros.html", {"livros": []})
lista = list(Livro.objects.all())
return render(request, "livros.html", {"livros": lista})
O HTML da entrada:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ribeira Django</title>
</head>
<body>
<h1>Biblioteca da Ribeira (Django)</h1>
<p>Servidor local. Abra só http://127.0.0.1:8000/</p>
<p><a href="/livros/">Livros</a> · <a href="/admin/">Admin</a></p>
</body>
</html>
lang="pt-BR" declara o idioma. O viewport evita a página minúscula no celular. A barra precisa mostrar 127.0.0.1. Isso não publica.
Erro comum: clicar em inicio.html no Explorador. O Django não entra. A página só existe depois do runserver.
Em /livros/ aparece o catálogo vazio. Está certo hoje: models.py ainda não define Livro. O capítulo 28 liga o catálogo e carrega livros fictícios.
Pare e experimente. Com o servidor ligado, mude uma frase do parágrafo em inicio.html, salve e recarregue http://127.0.0.1:8000/. Preveja só aquela frase nova.
Quando a home abrir em 127.0.0.1:8000, avance. Não publique. Não use dados reais.
Atividades
- O que o Django devolve ao navegador neste exemplo?
- Por que ativar
.venvantes dopip install? - Qual comando sobe o servidor só nesta máquina, na porta 8000?
Respostas comentadas
- Uma página HTML gerada no computador. A view escolhe o template. O navegador só desenha o que recebeu.
- Para o Django ficar isolado neste projeto. Sem o ambiente, o pacote pode ir para outro Python e o
manage.pynão encontra o framework. python manage.py runserver 127.0.0.1:8000. Depois abrahttp://127.0.0.1:8000/.
O arquivo completo
Referência do exemplo 27-django-introducao, reproduzida aqui para que você possa conferir sem sair da página.
manage.py
#!/usr/bin/env python
import os
import sys
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ribeira.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()
templates/livros.html
<!DOCTYPE html>
<html lang="pt-BR">
<head><meta charset="utf-8"/><title>Livros</title><style>
/* Apoio de leitura, teclado e tela estreita. */
img{max-width:100%;height:auto} html {overflow-wrap:anywhere} main {min-width:0} input,textarea,select,canvas {max-width:100%;box-sizing:border-box} fieldset {min-width:0}
pre {max-width:100%;overflow:auto} :focus-visible {outline:3px solid #0f3d3e;outline-offset:3px}
.skip {position:absolute;top:-5rem;left:1rem;background:#0f3d3e;color:white;padding:.5rem;z-index:9}.skip:focus {top:.5rem}
table {max-width:100%} td,th {overflow-wrap:anywhere}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
</style><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body><a class="skip" href="#conteudo">Pular para o conteúdo</a><main id="conteudo" tabindex="-1">
<h1>Livros</h1>
<ul>{% for livro in livros %}<li>{{ livro.titulo }} — {{ livro.autoria }}</li>{% empty %}<li>Nenhum título ainda. Use o admin.</li>{% endfor %}</ul>
</main></body>
</html>