00
:
00
:
00
:
00
‱Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.