Django-Verifikationsschleife
Vor Pull Requests, nach größeren Änderungen und vor der Bereitstellung ausführen, um die Qualität und Sicherheit der Django-Anwendung sicherzustellen.
Wann aktivieren
- Vor dem Öffnen eines Pull Requests für ein Django-Projekt
- Nach großen Modelländerungen, Migrationsupdates oder Abhängigkeitsupgrades
- Vor der Bereitstellung für Staging oder Produktion
- Bei Ausführung der vollständigen Pipeline: Umgebung → Lint → Test → Sicherheit → Bereitstellungsbereitschaft
- Überprüfung der Migrationssicherheit und Testabdeckung
Phase 1: Umgebungsprüfung
# Python-Version überprüfen
python --version # Sollte den Projektanforderungen entsprechen
# Virtuelle Umgebung prüfen
which python
pip list --outdated
# Umgebungsvariablen überprüfen
python -c "import os; import environ; print('DJANGO_SECRET_KEY gesetzt' if os.environ.get('DJANGO_SECRET_KEY') else 'FEHLT: DJANGO_SECRET_KEY')"
Wenn die Umgebung falsch konfiguriert ist, anhalten und beheben.
Phase 2: Code-Qualität & Formatierung
# Typüberprüfung
mypy . --config-file pyproject.toml
# Linting mit ruff
ruff check . --fix
# Formatierung mit black
black . --check
black . # Automatische Korrektur
# Imports sortieren
isort . --check-only
isort . # Automatische Korrektur
# Django-spezifische Prüfungen
python manage.py check --deploy
Häufige Probleme:
- Fehlende Typannotationen bei öffentlichen Funktionen
- PEP-8-Formatierungsverstöße
- Unsorierte Imports
- Debug-Einstellungen in der Produktionskonfiguration
Phase 3: Migrationen
# Unangewendete Migrationen prüfen
python manage.py showmigrations
# Fehlende Migrationen erstellen
python manage.py makemigrations --check
# Migrationen testweise anwenden
python manage.py migrate --plan
# Migrationen anwenden (Testumgebung)
python manage.py migrate
# Migrationskonflikte prüfen
python manage.py makemigrations --merge # Nur bei Konflikten
Bericht:
- Anzahl ausstehender Migrationen
- Eventuelle Migrationskonflikte
- Modelländerungen ohne Migrationen
Phase 4: Tests + Abdeckung
# Alle Tests mit pytest ausführen
pytest --cov=apps --cov-report=html --cov-report=term-missing --reuse-db
# Tests für eine bestimmte App ausführen
pytest apps/users/tests/
# Mit Markern ausführen
pytest -m "not slow" # Langsame Tests überspringen
pytest -m integration # Nur Integrationstests
# Coverage-Bericht öffnen
open htmlcov/index.html
Bericht:
- Gesamttests: X bestanden, Y fehlgeschlagen, Z übersprungen
- Gesamtabdeckung: XX%
- Aufteilung nach App
Coverage-Ziele:
| Komponente | Ziel |
|---|---|
| Modelle | 90%+ |
| Serializer | 85%+ |
| Views | 80%+ |
| Services | 90%+ |
| Gesamt | 80%+ |
Phase 5: Sicherheitsscan
# Abhängigkeitsschwachstellen
pip-audit
safety check --full-report
# Django-Sicherheitsprüfungen
python manage.py check --deploy
# Bandit-Sicherheitslinter
bandit -r . -f json -o bandit-report.json
# Secret-Scanning (falls gitleaks installiert)
gitleaks detect --source . --verbose
# Umgebungsvariablen prüfen
python -c "from django.core.exceptions import ImproperlyConfigured; from django.conf import settings; settings.DEBUG"
Bericht:
- Gefundene anfällige Abhängigkeiten
- Sicherheitskonfigurationsprobleme
- Erkannte hartcodierte Geheimnisse
- DEBUG-Modus-Status (sollte in Produktion False sein)
Phase 6: Django-Verwaltungsbefehle
# Modellprobleme prüfen
python manage.py check
# Statische Dateien sammeln
python manage.py collectstatic --noinput --clear
# Superuser erstellen (falls für Tests benötigt)
echo "from apps.users.models import User; User.objects.create_superuser('[email protected]', 'admin')" | python manage.py shell
# Datenbankintegrität prüfen
python manage.py check --database default
# Cache-Verifizierung (falls Redis verwendet wird)
python -c "from django.core.cache import cache; cache.set('test', 'value', 10); print(cache.get('test'))"
Phase 7: Leistungsprüfungen
# Django Debug Toolbar Ausgabe (auf N+1-Abfragen prüfen)
# Im Entwicklungsmodus mit DEBUG=True ausführen und eine Seite aufrufen
# Auf doppelte Abfragen im SQL-Panel achten
# Abfrageanzahl-Analyse
django-admin debugsqlshell # Falls django-debug-sqlshell installiert ist
# Fehlende Indizes prüfen
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
Bericht:
- Anzahl der Abfragen pro Seite (sollte < 50 für typische Seiten sein)
- Fehlende Datenbankindizes
- Erkannte doppelte Abfragen
Phase 8: Statische Assets
# npm-Abhängigkeiten prüfen (falls npm verwendet wird)
npm audit
npm audit fix
# Statische Dateien bauen (falls webpack/vite verwendet wird)
npm run build
# Statische Dateien überprüfen
ls -la staticfiles/
python manage.py findstatic css/style.css
Phase 9: Konfigurationsüberprüfung
# In Python-Shell ausführen, um Einstellungen zu überprüfen
python manage.py shell << EOF
from django.conf import settings
import os
# Kritische Prüfungen
checks = {
'DEBUG ist False': not settings.DEBUG,
'SECRET_KEY gesetzt': bool(settings.SECRET_KEY and len(settings.SECRET_KEY) > 30),
'ALLOWED_HOSTS gesetzt': len(settings.ALLOWED_HOSTS) > 0,
'HTTPS aktiviert': getattr(settings, 'SECURE_SSL_REDIRECT', False),
'HSTS aktiviert': getattr(settings, 'SECURE_HSTS_SECONDS', 0) > 0,
'Datenbank konfiguriert': settings.DATABASES['default']['ENGINE'] != 'django.db.backends.sqlite3',
}
for check, result in checks.items():
status = '✓' if result else '✗'
print(f"{status} {check}")
EOF
Phase 10: Logging-Konfiguration
# Logging-Ausgabe testen
python manage.py shell << EOF
import logging
logger = logging.getLogger('django')
logger.warning('Test-Warnmeldung')
logger.error('Test-Fehlermeldung')
EOF
# Logdateien prüfen (falls konfiguriert)
tail -f /var/log/django/django.log
Phase 11: API-Dokumentation (falls DRF)
# Schema generieren
python manage.py generateschema --format openapi-json > schema.json
# Schema validieren
# Prüfen, ob schema.json gültiges JSON ist
python -c "import json; json.load(open('schema.json'))"
# Swagger-Benutzeroberfläche aufrufen (falls drf-yasg verwendet wird)
# http://localhost:8000/swagger/ im Browser öffnen
Phase 12: Diff-Review
# Diff-Statistiken anzeigen
git diff --stat
# Tatsächliche Änderungen anzeigen
git diff
# Geänderte Dateien anzeigen
git diff --name-only
# Nach häufigen Problemen suchen
git diff | grep -i "todo\|fixme\|hack\|xxx"
git diff | grep "print(" # Debug-Anweisungen
git diff | grep "DEBUG = True" # Debug-Modus
git diff | grep "import pdb" # Debugger
Checkliste:
- Keine Debugging-Anweisungen (print, pdb, breakpoint())
- Keine TODO/FIXME-Kommentare in kritischem Code
- Keine hartcodierten Geheimnisse oder Anmeldedaten
- Datenbankmigrationen für Modelländerungen enthalten
- Konfigurationsänderungen dokumentiert
- Fehlerbehandlung für externe Aufrufe vorhanden
- Transaktionsmanagement falls erforderlich
Ausgabevorlage
DJANGO-VERIFIKATIONSBERICHT
============================
Phase 1: Umgebungsprüfung
✓ Python 3.11.5
✓ Virtuelle Umgebung aktiv
✓ Alle Umgebungsvariablen gesetzt
Phase 2: Code-Qualität
✓ mypy: Keine Typfehler
✗ ruff: 3 Probleme gefunden (automatisch korrigiert)
✓ black: Keine Formatierungsprobleme
✓ isort: Imports korrekt sortiert
✓ manage.py check: Keine Probleme
Phase 3: Migrationen
✓ Keine ausstehenden Migrationen
✓ Keine Migrationskonflikte
✓ Alle Modelle haben Migrationen
Phase 4: Tests + Abdeckung
Tests: 247 bestanden, 0 fehlgeschlagen, 5 übersprungen
Abdeckung:
Gesamt: 87%
users: 92%
products: 89%
orders: 85%
payments: 91%
Phase 5: Sicherheitsscan
✗ pip-audit: 2 Schwachstellen gefunden (Behebung erforderlich)
✓ safety check: Keine Probleme
✓ bandit: Keine Sicherheitsprobleme
✓ Keine Geheimnisse erkannt
✓ DEBUG = False
Phase 6: Django-Befehle
✓ collectstatic abgeschlossen
✓ Datenbankintegrität OK
✓ Cache-Backend erreichbar
Phase 7: Leistung
✓ Keine N+1-Abfragen erkannt
✓ Datenbankindizes konfiguriert
✓ Abfrageanzahl akzeptabel
Phase 8: Statische Assets
✓ npm audit: Keine Schwachstellen
✓ Assets erfolgreich gebaut
✓ Statische Dateien gesammelt
Phase 9: Konfiguration
✓ DEBUG = False
✓ SECRET_KEY konfiguriert
✓ ALLOWED_HOSTS gesetzt
✓ HTTPS aktiviert
✓ HSTS aktiviert
✓ Datenbank konfiguriert
Phase 10: Logging
✓ Logging konfiguriert
✓ Logdateien beschreibbar
Phase 11: API-Dokumentation
✓ Schema generiert
✓ Swagger-Benutzeroberfläche erreichbar
Phase 12: Diff-Review
Geänderte Dateien: 12
+450, -120 Zeilen
✓ Keine Debug-Anweisungen
✓ Keine hartcodierten Geheimnisse
✓ Migrationen enthalten
EMPFEHLUNG: WARNUNG: pip-audit-Schwachstellen vor der Bereitstellung beheben
NÄCHSTE SCHRITTE:
1. Anfällige Abhängigkeiten aktualisieren
2. Sicherheitsscan erneut ausführen
3. Für letzte Tests in Staging bereitstellen
Vorbereitung zur Bereitstellung - Checkliste
- Alle Tests bestehen
- Abdeckung ≥ 80%
- Keine Sicherheitsschwachstellen
- Keine ausstehenden Migrationen
- DEBUG = False in Produktionseinstellungen
- SECRET_KEY korrekt konfiguriert
- ALLOWED_HOSTS richtig gesetzt
- Datenbank-Backups aktiviert
- Statische Dateien gesammelt und ausgeliefert
- Logging konfiguriert und funktioniert
- Fehlerüberwachung (Sentry etc.) konfiguriert
- CDN konfiguriert (falls zutreffend)
- Redis/Cache-Backend konfiguriert
- Celery-Worker laufen (falls zutreffend)
- HTTPS/SSL konfiguriert
- Umgebungsvariablen dokumentiert
Kontinuierliche Integration
GitHub Actions Beispiel
# .github/workflows/django-verification.yml
name: Django-Verifikation
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: Python einrichten
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: pip cachen
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
- name: Abhängigkeiten installieren
run: |
pip install -r requirements.txt
pip install ruff black mypy pytest pytest-django pytest-cov bandit safety pip-audit
- name: Code-Qualitätsprüfungen
run: |
ruff check .
black . --check
isort . --check-only
mypy .
- name: Sicherheitsscan
run: |
bandit -r . -f json -o bandit-report.json
safety check --full-report
pip-audit
- name: Tests ausführen
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: Coverage hochladen
uses: codecov/codecov-action@v3
Kurzreferenz
| Prüfung | Befehl |
|---|---|
| Umgebung | python --version |
| Typüberprüfung | mypy . |
| Linting | ruff check . |
| Formatierung | black . --check |
| Migrationen | python manage.py makemigrations --check |
| Tests | pytest --cov=apps |
| Sicherheit | pip-audit && bandit -r . |
| Django-Prüfung | python manage.py check --deploy |
| Collectstatic | python manage.py collectstatic --noinput |
| Diff-Statistiken | git diff --stat |
Denken Sie daran: Automatisierte Verifikation erkennt häufige Probleme, ersetzt jedoch nicht die manuelle Codeüberprüfung und Tests in der Staging-Umgebung.