Loop de Verificação Django
Execute antes de PRs, após grandes alterações e pré-implantação para garantir qualidade e segurança da aplicação Django.
Quando Ativar
- Antes de abrir um pull request para um projeto Django
- Após grandes alterações de modelo, atualizações de migração ou upgrades de dependências
- Verificação pré-implantação para staging ou produção
- Execução do pipeline completo: ambiente → lint → teste → segurança → prontidão para deploy
- Validação de segurança de migrações e cobertura de testes
Fase 1: Verificação de Ambiente
# Verificar versão do Python
python --version # Deve corresponder aos requisitos do projeto
# Verificar ambiente virtual
which python
pip list --outdated
# Verificar variáveis de ambiente
python -c "import os; import environ; print('DJANGO_SECRET_KEY definida' if os.environ.get('DJANGO_SECRET_KEY') else 'FALTANDO: DJANGO_SECRET_KEY')"
Se o ambiente estiver mal configurado, pare e corrija.
Fase 2: Qualidade e Formatação de Código
# Verificação de tipos
mypy . --config-file pyproject.toml
# Linting com ruff
ruff check . --fix
# Formatação com black
black . --check
black . # Auto-correção
# Ordenação de imports
isort . --check-only
isort . # Auto-correção
# Verificações específicas do Django
python manage.py check --deploy
Problemas comuns:
- Falta de dicas de tipo em funções públicas
- Violações de formatação PEP 8
- Imports não ordenados
- Configurações de debug deixadas na configuração de produção
Fase 3: Migrações
# Verificar migrações não aplicadas
python manage.py showmigrations
# Criar migrações faltantes
python manage.py makemigrations --check
# Simular aplicação de migrações
python manage.py migrate --plan
# Aplicar migrações (ambiente de teste)
python manage.py migrate
# Verificar conflitos de migração
python manage.py makemigrations --merge # Apenas se existirem conflitos
Relatar:
- Número de migrações pendentes
- Quaisquer conflitos de migração
- Alterações de modelo sem migrações
Fase 4: Testes + Cobertura
# Executar todos os testes com pytest
pytest --cov=apps --cov-report=html --cov-report=term-missing --reuse-db
# Executar testes de um app específico
pytest apps/users/tests/
# Executar com marcadores
pytest -m "not slow" # Pular testes lentos
pytest -m integration # Apenas testes de integração
# Relatório de cobertura
open htmlcov/index.html
Relatar:
- Total de testes: X passaram, Y falharam, Z pulados
- Cobertura geral: XX%
- Divisão de cobertura por app
Metas de cobertura:
| Componente | Meta |
|---|---|
| Models | 90%+ |
| Serializers | 85%+ |
| Views | 80%+ |
| Services | 90%+ |
| Geral | 80%+ |
Fase 5: Varredura de Segurança
# Vulnerabilidades de dependências
pip-audit
safety check --full-report
# Verificações de segurança do Django
python manage.py check --deploy
# Linter de segurança Bandit
bandit -r . -f json -o bandit-report.json
# Varredura de segredos (se gitleaks estiver instalado)
gitleaks detect --source . --verbose
# Verificação de variáveis de ambiente
python -c "from django.core.exceptions import ImproperlyConfigured; from django.conf import settings; settings.DEBUG"
Relatar:
- Dependências vulneráveis encontradas
- Problemas de configuração de segurança
- Segredos codificados detectados
- Status do modo DEBUG (deve ser False em produção)
Fase 6: Comandos de Gerenciamento do Django
# Verificar problemas de modelo
python manage.py check
# Coletar arquivos estáticos
python manage.py collectstatic --noinput --clear
# Criar superusuário (se necessário para testes)
echo "from apps.users.models import User; User.objects.create_superuser('[email protected]', 'admin')" | python manage.py shell
# Integridade do banco de dados
python manage.py check --database default
# Verificação de cache (se usando Redis)
python -c "from django.core.cache import cache; cache.set('test', 'value', 10); print(cache.get('test'))"
Fase 7: Verificações de Performance
# Saída da Django Debug Toolbar (verificar consultas N+1)
# Execute em modo dev com DEBUG=True e acesse uma página
# Procure por consultas duplicadas no painel SQL
# Análise de contagem de consultas
django-admin debugsqlshell # Se django-debug-sqlshell estiver instalado
# Verificar índices ausentes
python manage.py shell << EOF
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("SELECT table_name, index_name FROM information_schema.statistics WHERE table_schema = 'public'")
print(cursor.fetchall())
EOF
Relatar:
- Número de consultas por página (deve ser < 50 para páginas típicas)
- Índices de banco de dados ausentes
- Consultas duplicadas detectadas
Fase 8: Ativos Estáticos
# Verificar dependências npm (se usando npm)
npm audit
npm audit fix
# Construir arquivos estáticos (se usando webpack/vite)
npm run build
# Verificar arquivos estáticos
ls -la staticfiles/
python manage.py findstatic css/style.css
Fase 9: Revisão de Configuração
# Execute no shell do Python para verificar configurações
python manage.py shell << EOF
from django.conf import settings
import os
# Verificações críticas
checks = {
'DEBUG é False': not settings.DEBUG,
'SECRET_KEY definida': bool(settings.SECRET_KEY and len(settings.SECRET_KEY) > 30),
'ALLOWED_HOSTS definido': len(settings.ALLOWED_HOSTS) > 0,
'HTTPS habilitado': getattr(settings, 'SECURE_SSL_REDIRECT', False),
'HSTS habilitado': getattr(settings, 'SECURE_HSTS_SECONDS', 0) > 0,
'Banco de dados configurado': settings.DATABASES['default']['ENGINE'] != 'django.db.backends.sqlite3',
}
for check, result in checks.items():
status = '✓' if result else '✗'
print(f"{status} {check}")
EOF
Fase 10: Configuração de Logging
# Testar saída de logging
python manage.py shell << EOF
import logging
logger = logging.getLogger('django')
logger.warning('Mensagem de aviso de teste')
logger.error('Mensagem de erro de teste')
EOF
# Verificar arquivos de log (se configurados)
tail -f /var/log/django/django.log
Fase 11: Documentação da API (se DRF)
# Gerar esquema
python manage.py generateschema --format openapi-json > schema.json
# Validar esquema
# Verificar se schema.json é JSON válido
python -c "import json; json.load(open('schema.json'))"
# Acessar Swagger UI (se usando drf-yasg)
# Visite http://localhost:8000/swagger/ no navegador
Fase 12: Revisão de Diff
# Mostrar estatísticas do diff
git diff --stat
# Mostrar alterações reais
git diff
# Mostrar arquivos alterados
git diff --name-only
# Verificar problemas comuns
git diff | grep -i "todo\|fixme\|hack\|xxx"
git diff | grep "print(" # Declarações de debug
git diff | grep "DEBUG = True" # Modo debug
git diff | grep "import pdb" # Debugger
Checklist:
- Nenhuma declaração de debug (print, pdb, breakpoint())
- Nenhum comentário TODO/FIXME em código crítico
- Nenhum segredo ou credencial codificada
- Migrações de banco de dados incluídas para alterações de modelo
- Alterações de configuração documentadas
- Tratamento de erros presente para chamadas externas
- Gerenciamento de transações onde necessário
Template de Saída
RELATÓRIO DE VERIFICAÇÃO DJANGO
==========================
Fase 1: Verificação de Ambiente
✓ Python 3.11.5
✓ Ambiente virtual ativo
✓ Todas as variáveis de ambiente definidas
Fase 2: Qualidade de Código
✓ mypy: Nenhum erro de tipo
✗ ruff: 3 problemas encontrados (auto-corrigidos)
✓ black: Nenhum problema de formatação
✓ isort: Imports devidamente ordenados
✓ manage.py check: Nenhum problema
Fase 3: Migrações
✓ Nenhuma migração não aplicada
✓ Nenhum conflito de migração
✓ Todos os modelos têm migrações
Fase 4: Testes + Cobertura
Testes: 247 passaram, 0 falharam, 5 pulados
Cobertura:
Geral: 87%
users: 92%
products: 89%
orders: 85%
payments: 91%
Fase 5: Varredura de Segurança
✗ pip-audit: 2 vulnerabilidades encontradas (correção necessária)
✓ safety check: Nenhum problema
✓ bandit: Nenhum problema de segurança
✓ Nenhum segredo detectado
✓ DEBUG = False
Fase 6: Comandos Django
✓ collectstatic concluído
✓ Integridade do banco de dados OK
✓ Backend de cache acessível
Fase 7: Performance
✓ Nenhuma consulta N+1 detectada
✓ Índices de banco de dados configurados
✓ Contagem de consultas aceitável
Fase 8: Ativos Estáticos
✓ npm audit: Nenhuma vulnerabilidade
✓ Ativos construídos com sucesso
✓ Arquivos estáticos coletados
Fase 9: Configuração
✓ DEBUG = False
✓ SECRET_KEY configurada
✓ ALLOWED_HOSTS definido
✓ HTTPS habilitado
✓ HSTS habilitado
✓ Banco de dados configurado
Fase 10: Logging
✓ Logging configurado
✓ Arquivos de log graváveis
Fase 11: Documentação da API
✓ Esquema gerado
✓ Swagger UI acessível
Fase 12: Revisão de Diff
Arquivos alterados: 12
+450, -120 linhas
✓ Nenhuma declaração de debug
✓ Nenhum segredo codificado
✓ Migrações incluídas
RECOMENDAÇÃO: AVISO: Corrija as vulnerabilidades do pip-audit antes de implantar
PRÓXIMOS PASSOS:
1. Atualizar dependências vulneráveis
2. Reexecutar varredura de segurança
3. Implantar em staging para testes finais
Checklist Pré-Implantação
- Todos os testes passando
- Cobertura ≥ 80%
- Nenhuma vulnerabilidade de segurança
- Nenhuma migração não aplicada
- DEBUG = False nas configurações de produção
- SECRET_KEY configurada corretamente
- ALLOWED_HOSTS definido corretamente
- Backups de banco de dados habilitados
- Arquivos estáticos coletados e servidos
- Logging configurado e funcionando
- Monitoramento de erros (Sentry, etc.) configurado
- CDN configurada (se aplicável)
- Redis/backend de cache configurado
- Workers Celery em execução (se aplicável)
- HTTPS/SSL configurado
- Variáveis de ambiente documentadas
Integração Contínua
Exemplo do GitHub Actions
# .github/workflows/django-verification.yml
name: Verificação Django
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v3
- name: Configurar Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Cache pip
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
- name: Instalar dependências
run: |
pip install -r requirements.txt
pip install ruff black mypy pytest pytest-django pytest-cov bandit safety pip-audit
- name: Verificações de qualidade de código
run: |
ruff check .
black . --check
isort . --check-only
mypy .
- name: Varredura de segurança
run: |
bandit -r . -f json -o bandit-report.json
safety check --full-report
pip-audit
- name: Executar testes
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
DJANGO_SECRET_KEY: test-secret-key
run: |
pytest --cov=apps --cov-report=xml --cov-report=term-missing
- name: Enviar cobertura
uses: codecov/codecov-action@v3
Referência Rápida
| Verificação | Comando |
|---|---|
| Ambiente | python --version |
| Verificação de tipos | mypy . |
| Linting | ruff check . |
| Formatação | black . --check |
| Migrações | python manage.py makemigrations --check |
| Testes | pytest --cov=apps |
| Segurança | pip-audit && bandit -r . |
| Verificação Django | python manage.py check --deploy |
| Coletar estáticos | python manage.py collectstatic --noinput |
| Estatísticas do diff | git diff --stat |
Lembre-se: A verificação automatizada captura problemas comuns, mas não substitui a revisão manual de código e os testes no ambiente de staging.