---
title: "Come creare comandi django-admin personalizzati"
version: 4.2
locale: it
source: https://docs.djangoproject.com/it/4.2/howto/custom-management-commands/
canonical: https://djangodocs.dev/it/4.2/howto/custom-management-commands/
---
# Come creare comandi `django-admin` personalizzati

Le applicazioni possono registrare le proprie azioni con `manage.py`. Per esempio, potresti voler aggiungere una azione `manage.py` per una applicazione Django che stai distribuendo. In questo documento, costruiremo un comando personalizzato `closepoll` per l’applicazione `polls` dal [tutorial](/it/4.2/intro/tutorial01/).

To do this, add a `management/commands` directory to the application. Django
will register a `manage.py` command for each Python module in that directory
whose name doesn’t begin with an underscore. For example:

```text
polls/
    __init__.py
    models.py
    management/
        __init__.py
        commands/
            __init__.py
            _private.py
            closepoll.py
    tests.py
    views.py
```

In questo esempio, il comando `closepoll` sarà reso disponibile a qualsiasi progetto che includa l’applicazione `polls` in [`INSTALLED_APPS`](/it/4.2/ref/settings/#std-setting-INSTALLED_APPS).

Il modulo `_private.py` non sarà disponibile come comando di management.

Il modulo `closepoll.py` ha un solo requisito – deve definire una classe `Command` che estenda [`BaseCommand`](#django.core.management.BaseCommand) o una delle sue [sottoclassi](#ref-basecommand-subclasses).

> **Script standalone**
>
> Il comandi di management personalizzati sono utili soprattutto per lanciare script standalone o per script che sono eseguiti periodicamente con il crontab di UNIX o dal pannello di controllo per la pianificazione dei task di Windows.

Per implementare il comando, modifica `polls/management/commands/closepoll.py` in questo modo :

```
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll

class Command(BaseCommand):
    help = "Closes the specified poll for voting"

    def add_arguments(self, parser):
        parser.add_argument("poll_ids", nargs="+", type=int)

    def handle(self, *args, **options):
        for poll_id in options["poll_ids"]:
            try:
                poll = Poll.objects.get(pk=poll_id)
            except Poll.DoesNotExist:
                raise CommandError('Poll "%s" does not exist' % poll_id)

            poll.opened = False
            poll.save()

            self.stdout.write(
                self.style.SUCCESS('Successfully closed poll "%s"' % poll_id)
            )
```

> **Note**
>
> Quando utilizzi i comandi di management personalizzati e vuoi ottenere dell’output su console, dovresti scrivere su `self.stdout` e `self.stderr`, invece che direttamente su stdout\` and `stderr`. Utilizzando questi proxy, diventa molto più facile testare il tuo comando personalizzato. Nota anache che non hai bisogno di terminare i messaggi con il carattere di newline, sarà aggiunto automaticamente, a meno che tu non specifichi il parametro `ending`:
>
> ```
> self.stdout.write("Unterminated line", ending="")
> ```

Il nuovo comando personalizzato potrà essere chiamato con `python manage.py closepoll <poll_ids>`.

Il metodo `handle()` prende uno o più `poll_ids` ed imposta `poll.opened` a `False` per ognuno di essi. Se l’utente fa riferimento ad un poll non esistente, viene sollevato un [`CommandError`](#django.core.management.CommandError). L’attributo `poll.opened` non esiste nel [tutorial](/it/4.2/intro/tutorial02/)  ed è stato aggiunto a `polls.models.Question` per questo esempio.

## Accetta argomenti opzionali

Lo stesso `closepoll`  può essere modificato facilmente per cancellare un dato poll invece che chiuderlo accettando opzioni sulla command line. Queste opzioni personalizzate possono essere aggiunte nel metodo [`add_arguments()`](#django.core.management.BaseCommand.add_arguments) così:

```
class Command(BaseCommand):
    def add_arguments(self, parser):
        # Positional arguments
        parser.add_argument("poll_ids", nargs="+", type=int)

        # Named (optional) arguments
        parser.add_argument(
            "--delete",
            action="store_true",
            help="Delete poll instead of closing it",
        )

    def handle(self, *args, **options):
        # ...
        if options["delete"]:
            poll.delete()
        # ...
```

L’opzione (`delete` nel nostro esempio) è disponibile nel dizionario di parametri delle opzioni del metodo handle. Vedi la documentazione di Python di [`argparse`](https://docs.python.org/3/library/argparse.html#module-argparse) per saperne di più sull’utilizzo di `add_argument`.

Oltre ad essere in grado di aggiungere opzioni personalizzate per la command line, tutti i [comandi di management](/it/4.2/ref/django-admin/)  possono accettare alcune opzioni di default come [`--verbosity`](/it/4.2/ref/django-admin/#cmdoption-verbosity) e  [`--traceback`](/it/4.2/ref/django-admin/#cmdoption-traceback).

## Commandi di gestione e traduzioni/locale

Di default, i comandi di management sono eseguiti con il locale che è correntemente attivo.

Se, per qualche ragione, il tuo comando di management personalizzato deve girare senza un locale attivo (per esempio, per evitare che il contenuto tradotto venga inserito nel database), disattiva le traduzioni usando il decoratore `@no_translations`  sul tuo metodo [`handle()`](#django.core.management.BaseCommand.handle)

```
from django.core.management.base import BaseCommand, no_translations

class Command(BaseCommand):
    ...

    @no_translations
    def handle(self, *args, **options):
        ...
```

Dal momento che la disattivazione della traduzione richiede l’accesso alle impostazioni di configurazione, il decoratore non può essere usato per comandi che funzionino senza impostazioni di configurazione.

## Testing

Informazioni su come testare i comandi di management personalizzati possono essere trovate nei [documenti di testing](/it/4.2/topics/testing/tools/#topics-testing-management-commands).

## Override dei comandi

Django registra i comandi built-in e poi cerca comandi in [`INSTALLED_APPS`](/it/4.2/ref/settings/#std-setting-INSTALLED_APPS) in senso inverso. Durante la ricerca, se un nome di comando duplica un comando già registrato, fa override su quello precedente.

In altre parole, per fare override di un comando, il nuovo comando deve avere lo stesso nome e la sua app deve trovarsi prima di quella del comando su cui fare override in [`INSTALLED_APPS`](/it/4.2/ref/settings/#std-setting-INSTALLED_APPS).

I comandi di management di app di terze parti che sono stati sovrascritti in modo non intenzionale posso essere resi disponibili con un nuovo nome creando un nuovo comando in una delle app del tuo progetto (che si trovi in ordine prima dell’app di terze parti in [`INSTALLED_APPS`](/it/4.2/ref/settings/#std-setting-INSTALLED_APPS)) che importi il `Command` del comando sovrascritto.

## Oggetti Command

#### `class BaseCommand`

La classe di base da cui, in ultima analisi, tutti i comandi di management derivano.

Usa questa classe se vuoi accedere a tutti i meccanismi che fanno parsing degli argomenti di command-line e cercano di capire quale codice chiamare in risposta; se non hai bisogno di cambiare questo comportamento, considera di usare una delle sue [sottoclassi](#ref-basecommand-subclasses).

Fare una sottoclasse della classe [`BaseCommand`](#django.core.management.BaseCommand) ti richiede di implementare il metodo [`handle()`](#django.core.management.BaseCommand.handle).

### Attributi

Tutti gli attributi possono essere impostati nella tua classe derivata e possono essere usati nelle [sottoclassi](#ref-basecommand-subclasses) di [`BaseCommand`](#django.core.management.BaseCommand).

#### `BaseCommand.help`

Una breve descrizione del comando, che sarà stampata nel messaggio di aiuto quando l’utente lancia il comando `python manage.py help <command>`.

#### `BaseCommand.missing_args_message`

Se il tuo comando definisce degli argomenti posizionali obbligatori, puoi personalizzare il messaggio di errore restituito in caso di argomenti mancanti. Quello di default è restituito da [`argparse`](https://docs.python.org/3/library/argparse.html#module-argparse) («too few arguments»).

#### `BaseCommand.output_transaction`

Un booleano che indica se il comando mostra in output uno statement SQL; se `True`, l’output sarà automaticamente inserito tra `BEGIN;` e `COMMIT;`. Il valore predefinito è `False`.

#### `BaseCommand.requires_migrations_checks`

Un booleano; se `True`, il comando stampa un messaggio di warning se il set di migrazioni su disco non corrisponde a quelle sul database. Un warning non impedisce l’esecuzione del comando. Il valore predefinito è `False`.

#### `BaseCommand.requires_system_checks`

Un lista di tuple di tag, per esempio `[Tags.staticfiles, Tags.models]`. Il sistema controlla che la registrazione nei tag scelti sia sottoposta a controllo di errori prima di eseguire il comando. Il valore `'__all__'` può essere usato per specificare che tutti i controlli siano eseguiti. Il valore predefinito è `'__all__'`.

#### `BaseCommand.style`

Un attributo di istanza che aiuta a creare output colorato quando si scrive su `stdout` o `stderr`. Per esempio:

```
self.stdout.write(self.style.SUCCESS("..."))
```

Vedi [Syntax coloring](/it/4.2/ref/django-admin/#syntax-coloring) per imparare come modificare la palette di colori e visualizzare gli stili disponibili (usa le versioni maiuscole dei «ruoli» descritti in quella sezione).

Se passi l’opzione [`--no-color`](/it/4.2/ref/django-admin/#cmdoption-no-color) quando lanci il comando, tutte le chiamate `self.style()` restituiranno la stringa originale senza colori.

#### `BaseCommand.suppressed_base_arguments`

Le opzioni dei comandi di default da sopprimere nell’output dell’help. Dovrebbe essere un set di nomi di opzione (per es. `'--verbosity'`). I valori di default per tutte le opzioni soppresse vengono comunque passati.

### Metodi

La classe [`BaseCommand`](#django.core.management.BaseCommand) ha pochi metodi che possono essere sovrascritti ma solo il metodo [`handle()`](#django.core.management.BaseCommand.handle) deve essere implementato.

> **Implementazione di un constructor in una subclasse**
>
> Se implementi `__init__` nella tua sottoclasse di [`BaseCommand`](#django.core.management.BaseCommand), devi chiamare `__init__` di [`BaseCommand`](#django.core.management.BaseCommand):
>
> ```
> class Command(BaseCommand):
>     def __init__(self, *args, **kwargs):
>         super().__init__(*args, **kwargs)
>         # ...
> ```

#### `BaseCommand.create_parser(prog_name, subcommand, **kwargs)`

Restituisce una istanza di `CommandParser`, che è una sottoclasse di [`ArgumentParser`](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser) con qualche personalizzazione per Django.

Puoi personalizzare l’istanza sovrascrivendo questo metodo e chiamando `super()` con parametri `kwargs` [`ArgumentParser`](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser).

#### `BaseCommand.add_arguments(parser)`

L’entry point per aggiungere argomenti del parser per gestire gli argomenti della command line passati al comando. I comandi personalizzati dovrebbero sovrascrivere questo metodo per aggiungere sia argomenti facoltativi che posizionali che siano accettati dal comando. Non è necessario chiamare `super()` quando si utilizza una sottoclasse di `BaseCommand`.

#### `BaseCommand.get_version()`

Restituisce la versione di Django, che dovrebbe essere corretta per tutti i comandi Django built-in. I comandi forniti dall’utente possono sovrascrivere questo metodo per restituire la propria versione.

#### `BaseCommand.execute(*args, **options)`

Cerca di eseguire questo comando, facendo i controlli di sistema se necessario (come controllato con l’attributo [`requires_system_checks`](#django.core.management.BaseCommand.requires_system_checks)). Se il comando solleva [`CommandError`](#django.core.management.CommandError), questo viene intercettato e stampato su `stderr`.

> **Chiamata di un commando di ?gestione? nel tuo codice**
>
> execute()\` non dovrebbe essere chiamato direttamente dal tuo codice per eseguire un comando. Usa invece [`call_command()`](/it/4.2/ref/django-admin/#django.core.management.call_command).

#### `BaseCommand.handle(*args, **options)`

La logica attuale del comando. Le sottoclassi devono implementare questo metodo

Può restituire una stringa che sarà stampata su `stdout` (tra `BEGIN;` e `COMMIT;` se [`output_transaction`](#django.core.management.BaseCommand.output_transaction) è `True`).

#### `BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)`

Usa il framework di controlli di sistema per ispezionare l’intero progetto Django in cerca di potenziali problemi. I problemi gravi sono segnalati cpme [`CommandError`](#django.core.management.CommandError); i warning sono stampati su `stderr`; le notifiche minori sono stampate su `stdout`.

Se `app_configs` e `tags` sono entrambi `None`, sono effettuati tutti i controlli di sistema. `tags` può essere una lista di tag di controllo, come `compatibility` o `models`.

### sottoclassi `BaseCommand`

#### `class AppCommand`

Un comando di gestione che accetta una o più etichette di applicazioni installate come argomenti e fa qualcosa con ciascuna di esse.

Piuttosto che implementare [`handle()`](#django.core.management.BaseCommand.handle), le sottoclassi devono implementare [`handle_app_config()`](#django.core.management.AppCommand.handle_app_config), che sarà chiamata una volta per ogni applicazione.

#### `AppCommand.handle_app_config(app_config, **options)`

Effettua le azioni del comando per `app_config`, che sarà una istanza di [`AppConfig`](/it/4.2/ref/applications/#django.apps.AppConfig) corrispondente ad una etichetta di applicazione fornita sulla linea di comando.

#### `class LabelCommand`

Un comando di gestione che accetta uno o più argomenti arbitrari (etichette) dalla linea di comando e fa qualcosa con ciascuno di essi.

Piuttosto che implementare [`handle()`](#django.core.management.BaseCommand.handle), le sottoclassi devono implmentare [`handle_label()`](#django.core.management.LabelCommand.handle_label), che sarà chiamato una volta per ogni etichetta.

#### `LabelCommand.label`

Una stringa che descrive gli argomenti arbitrari forniti al comando. La stringa viene usata nel testo di utilizzo e nei messaggi di errore del comando. Di default è pari a `'label'`.

#### `LabelCommand.handle_label(label, **options)`

Effettua le azioni del comando per `label`, che sarà la stringa come è fornita dalla riga di comando.

### Eccezioni di comando

#### `exception CommandError(returncode=1)`

Una classe di eccezione che indica un problema mentre si esegue un comando di gestione.

Se questa eccezione viene sollevata durante l’esecuzione di un comando di management da una console a linea di comando, sarà gestito e trasformato in un messaggio di errore stampato in modo gradevole verso lo stream di output appropriato (per es. `stderr`); di conseguenza, sollevare questa eccezione (con una descrizione sensibile dell’errore) è la modalità preferita di indicare che qualcosa è andato storto durante l’esecuzione di un comando. Essa accetta l’argomento opzionale `returncode` per personalizzare l’exit status del comando di management, usando [`sys.exit()`](https://docs.python.org/3/library/sys.html#sys.exit).

Se il comando di gestione è chiamato dal codice con [`call_command()`](/it/4.2/ref/django-admin/#django.core.management.call_command), è tuo compito catturare l’eccezione quando è necessario.
