Gestione Comandi
Django mette a disposizione un potente sistema di management commands che permette di creare comandi personalizzati eseguibili tramite python manage.py. Questi comandi sono ideali per operazioni di manutenzione, importazione dati, pulizia del database e qualsiasi automazione necessaria al progetto.
Struttura dei Comandi
I comandi personalizzati devono essere posizionati nella cartella management/commands/ della tua app Django:
myapp/
management/
__init__.py
commands/
__init__.py
mio_comando.py
Creare un Comando Base
Ogni comando estende la classe BaseCommand e implementa il metodo handle():
# myapp/management/commands/saluta.py
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Un semplice comando di saluto"
def handle(self, *args, **options):
self.stdout.write("Ciao dal comando personalizzato!")
Esecuzione:
python manage.py saluta
Aggiungere Argomenti
Usa il metodo add_arguments() per definire argomenti posizionali e opzionali:
# myapp/management/commands/crea_utenti.py
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User
class Command(BaseCommand):
help = "Crea un numero specificato di utenti di test"
def add_arguments(self, parser):
# Argomento posizionale obbligatorio
parser.add_argument("numero", type=int, help="Numero di utenti da creare")
# Argomenti opzionali
parser.add_argument(
"--prefisso",
type=str,
default="utente",
help="Prefisso per il nome utente (default: utente)",
)
parser.add_argument(
"--admin",
action="store_true",
help="Crea utenti come superuser",
)
def handle(self, *args, **options):
numero = options["numero"]
prefisso = options["prefisso"]
is_admin = options["admin"]
for i in range(numero):
username = f"{prefisso}_{i + 1}"
if is_admin:
User.objects.create_superuser(username=username, password="test1234")
else:
User.objects.create_user(username=username, password="test1234")
self.stdout.write(f"Creato utente: {username}")
self.stdout.write(
self.style.SUCCESS(f"Creati {numero} utenti con successo!")
)
Esecuzione con argomenti:
python manage.py crea_utenti 10 --prefisso test --admin
Output con Stili
Django fornisce stili predefiniti per colorare lâoutput nel terminale:
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Dimostra gli stili di output"
def handle(self, *args, **options):
self.stdout.write(self.style.SUCCESS("Operazione riuscita!"))
self.stdout.write(self.style.ERROR("Si e verificato un errore!"))
self.stdout.write(self.style.WARNING("Attenzione!"))
self.stdout.write(self.style.NOTICE("Nota informativa"))
self.stdout.write(self.style.SQL_KEYWORD("SELECT"))
# Output su stderr
self.stderr.write("Messaggio di errore su stderr")
Gestione degli Errori
Usa CommandError per segnalare errori che interrompono il comando:
from django.core.management.base import BaseCommand, CommandError
from myapp.models import Articolo
class Command(BaseCommand):
help = "Pubblica un articolo dato il suo ID"
def add_arguments(self, parser):
parser.add_argument("articolo_id", type=int)
def handle(self, *args, **options):
articolo_id = options["articolo_id"]
try:
articolo = Articolo.objects.get(pk=articolo_id)
except Articolo.DoesNotExist:
raise CommandError(f"Articolo con ID {articolo_id} non trovato")
articolo.pubblicato = True
articolo.save()
self.stdout.write(
self.style.SUCCESS(f'Articolo "{articolo.titolo}" pubblicato!')
)
Chiamare Comandi Programmaticamente
Puoi eseguire management commands direttamente dal codice Python con call_command:
from django.core.management import call_command
# Chiamata semplice
call_command("migrate")
# Con argomenti
call_command("crea_utenti", 5, prefisso="demo")
# Cattura output
from io import StringIO
output = StringIO()
call_command("saluta", stdout=output)
risultato = output.getvalue()
Esempio Pratico: Pulizia Dati
# myapp/management/commands/pulisci_sessioni.py
from django.core.management.base import BaseCommand
from django.contrib.sessions.models import Session
from django.utils import timezone
class Command(BaseCommand):
help = "Elimina le sessioni scadute dal database"
def add_arguments(self, parser):
parser.add_argument(
"--dry-run",
action="store_true",
help="Mostra quante sessioni verrebbero eliminate senza eliminarle",
)
def handle(self, *args, **options):
scadute = Session.objects.filter(expire_date__lt=timezone.now())
conteggio = scadute.count()
if options["dry_run"]:
self.stdout.write(f"Sessioni scadute trovate: {conteggio}")
else:
scadute.delete()
self.stdout.write(
self.style.SUCCESS(f"Eliminate {conteggio} sessioni scadute")
)
Conclusione
I management commands personalizzati sono uno strumento essenziale in Django per automatizzare operazioni ricorrenti. Grazie a BaseCommand, add_arguments() e call_command(), puoi creare script robusti e ben integrati nel framework, completi di gestione errori, output formattato e argomenti flessibili.