# Documentação Django 5.2.8

# Como criar comandos `django-admin` customizados

As aplicações podem registrar suas próprias ações com `manage.py`. Por exemplo, você pode querer adicionar uma ação `manage.py` para uma aplicação Django que você está distribuindo. Neste documento, construiremos um comando customizado `closepoll` para a aplicação `polls` do tutorial.

Para fazer isso, adicione um diretório `management/commands` na aplicação. Django irá registrar um comando `manage.py` para cada módulo Python naquele diretório cujo nome não comece com um sublinhado. Por exemplo:

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

Neste exemplo, o comando `closepoll` estará disponível a qualquer projeto que inclua a aplicação `polls` em `INSTALLED_APPS`.

O módulo `_private.py` não estará disponível como um comando de gerenciamento.

O módulo `closepoll.py` tem apenas uma exigência – deve definir uma classe `Command` que estende `BaseCommand` ou uma de suas subclasses.

Scripts autônomos

Comandos de gerenciamento customizados, são especialmente úteis para a execução de scripts independentes ou para scripts que são periodicamente executados a partir do crontab do UNIX ou do painel de controle de tarefas agendadas do Windows.

Para implementar o comando, edite `polls/management/commands/closepoll.py` para que fique assim:

    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)
                )

Nota

Quando estiver usando comandos de gerenciamento e desejar enviar a saída para console, deve se escrever para o `self.stdout` e `self.stderr`, ao invés de imprimir para o `stdout` e `stderr` diretamente. Ao usar esses proxies, torna-se muito mais fácil para testar o seu comando personalizado. Observe também que você não precisa terminar mensagens com um caractere de nova linha, este será adicionado automaticamente, a menos que você especifique o parâmetro `ending`:

    self.stdout.write("Unterminated line", ending="")

O novo comando personalizado pode ser chamado usando `python manage.py closepoll <poll_ids>`.

O método `handle()` usa um ou mais `poll_ids` e altera o “poll.opened” para `False` para cada um. Se o usuário referenciar qualquer enquete inexistente, uma exceção será levantada `CommandError`. O atributo `poll.opened` não existe no tutorial e foi adicionado em `polls.models.Question` para este exemplo.

## Aceitando argumentos opcionais

O mesmo `closepoll` poderia ser facilmente modificado para excluir uma determinada enquete, ao invés de fechá-la, aceitando as opções de linha de comando adicionais. Estas opções personalizadas podem ser adicionadas no método `add_arguments()` assim:

    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()
            # ...

The option (`delete` in our example) is available in the options dict parameter of the handle method. See the `argparse` Python documentation for more about `add_argument` usage.

Além de ser capaz de adicionar opções personalizadas de linha de comando, todos comandos de gereciamento aceitam algumas opções padrão, tais como :opção:`--verbosity` e :opção:`--traceback`.

## Comandos de gerenciamento e localidades

Por padrão, comandos de gerenciamento são executados com a localidade corrente ativa.

Se, por alguma razão, seu comando de gerenciamento personalizado precise ser executado sem um local ativo (por exemplo, para evitar que o conteúdo traduzido seja inserido dentro do banco de dados), desative a tradução utilizado o decorator `@no_translations` no seu método `handle()`:

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

    class Command(BaseCommand):
        ...

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

Como a desativação da tradução requer acesso as configurações definidas, os decorator’s não podem ser utilizados por comandos que trabalham sem configurações pré definidas.

## Testando

Informações sobre como testar comandos de gerenciamento personalizados pode ser encontradas na documentação de teste.

## Sobrescrevendo comandos.

Django registra os comandos internos e depois procura os comandos em `INSTALLED_APPS` em orderm reversa. Durante a busca, se um comando duplica um comando já registrado, o novo comando encontrado substitui o primeiro.

Em outras palavras, para sobrescrever um comando, o novo comando precisa ter o mesmo nome e seu app precisa estar antes do comando da app a ser sobrescrito em : setting:INSTALLED_APPS.

Comandos de gerenciamento de aplicações de terceiros que foram sobrescritos de maneira nao intencional podem se tornar disponíveis sob um novo nome através da criação de um novo comando em um dos apps do projeto (colocado antes da aplicação de terceiros em :setting:`INSTALLED_APPS) o qual importa o ‘Comando’ do comando sobrescrito.

## Objetos Command

class BaseCommand

A classe base a partir da qual todos os comandos de gestão, em última análise derivam.

Use esta classe se você quer acesso a todos os mecanismos que realizam o parse dos argumentos da linha de comando e verificar qual código chamar em resposta; se você não precisa mudar este comportamento, considere usar uma dessas subclasses.

Subclasssing a classe `BaseCommand` requer que você implemente o método `handle()`.

### Atributos

Todos os atributos podem ser definidos em sua classe derivada e podem ser usados nas subclasses de `BaseCommand`

BaseCommand.help

  Uma breve descrição do comando, que será impresso na mensagem de ajuda quando o usuário executar o comando `python manage.py help <command>`.

BaseCommand.missing_args_message

  If your command defines mandatory positional arguments, you can customize the message error returned in the case of missing arguments. The default is output by `argparse` (“too few arguments”).

BaseCommand.output_transaction

  Um booleano que indica como os comandos retornam SQL “statements”; Se `True`, a saída será automaticamente envolvido com `BEGIN;` e `COMMIT;`. O valor padrão é `False`.

BaseCommand.requires_migrations_checks

  Um booleano; Se `True`, o comando “printa” um alerta se o conjunto de migrações no disco não estiver de acordo com as migrações no banco de dados. Um alerta não previne o comando de ser executado. O valor padrão é `False`.

BaseCommand.requires_system_checks

  Uma lista ou tupla de tags, e. g. “[Tags.staticfiles, Tags.models]”. O sistema checa :ref’registrado nas tags escolhidas’ <registering-labeling-checks>’serão verificados por erros antes de executar o comando. O valor “__all__” pode ser usado para especificar que todas as checagens devem ser realizadas. Valor pré-definido é “__all__”

BaseCommand.style

  Um atributo de instância que ajuda a criar uma saída colorida quando se escreve no `stdout` ou `stderr`. Por exemplo:

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

  Veja sintaxe-coloring para aprender como modificar a paleta de cores e ver os estilos disponíveis (use caixa-alta das versões das opções descritas nessa seção).

  Se você passar a opção `--no-color` ao executar o seu comando, todas as chamadas `self.style()` retornarão a string original sem colorir.

BaseCommand.suppressed_base_arguments

  As opções de comando padrão a serem suprimidas na saída de ajuda. Este deve ser um conjunto de nomes de opções (por exemplo, `'--verbosity'`). Os valores padrão para as opções suprimidas ainda são passados.

### Métodos

`BaseCommand` tem alguns métodos que podem ser sobrescritos mas apenas o método `handle()` deve ser implementado.

Implementando um construtor em uma subclasse

Se você implementar `__init__` em sua subclasse de `BaseCommand`, você deve chamar: o `__init__` do class:` BaseCommand`:

    class Command(BaseCommand):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # ...

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

  Retorna uma instância de `CommandParser`, o qual é uma classe: argparse.ArgumentParser subclasse, com algumas personalizações para o Django.

  Você pode customizar a instância por sobrecarga desse método, chamando `super()` com `kwargs` da classe:~argparse.ArgumentParser como parâmetro.

BaseCommand.add_arguments(parser)

  Ponto de entrada para passar um “parser” como argumento para lidar com os argumentos da linha de comando passados ao comando. Comandos personalizados devem sobrescrever este método para adicionar ambos argumentos posicionais e opicionais aceitos pelo comando. Não é necessário chamar o `super()` quando for uma subclasse de `BaseCommand`.

BaseCommand.get_version()

  Retorna a versão do Django, que deve ser a correta para todos os comandos internos do Django. É possível sobrescrever este método para que comandos fornecidos pelo usuário possam retornar a sua própria versão.

BaseCommand.execute(*args, **options)

  Tenta executar este comando, verificando o sistema se necessário (conforme controlado pelo atributo `requires_system_checks`). Se o comando gera um `CommandError`, ele é interceptado e impresso em `stderr`.

Chamando um comando de gestão dentro do seu código

`execute()` não deve ser chamado diretamente do seu código para executar um comando. Ao invés disso, use `call_command()` .

BaseCommand.handle(*args, **options)

  A lógica atual do comando. Subclasses devem implementar este método.

  Pode retornar uma string tal qual será impressa no “stdout” (acrescido por “BEGIN;” e “COMMIT;” se :attr:’output_transaction’ for “True”).

BaseCommand.check(app_configs=None, tags=None, display_num_errors=False, include_deployment_checks=False, fail_level=checks.ERROR, databases=None)

  Usa a estrutura de verificação do sistema para inspecionar todo o projeto Django em busca de possíveis problemas. Problemas sérios são levantados como `CommandError`; avisos são emitidos para `stderr`; notificações menores são enviadas para `stdout`.

  Se `app_configs` e `tags` forem ambas `None`, todas as checagens do sistema serão performadas exceto checagens relacionados à implatanção e banco de dados. `tags` pode ser uma lista de rótulos para verificar, como `compatibility` ou `models`.

  Você pode informar `include_deployment_checks=True` para também executar verficações de implantação, e uma lista de apelidos de banco de dados em `databases` para executar verificações relacionadas à banco de dados nestes.

BaseCommand.get_check_kwargs(options)
  New in Django 5.2.

  Supplies kwargs for the call to `check()`, including transforming the value of `requires_system_checks` to the `tag` kwarg.

  Override this method to change the values supplied to `check()`. For example, to opt into database related checks you can override `get_check_kwargs()` as follows:

      def get_check_kwargs(self, options):
          kwargs = super().get_check_kwargs(options)
          return {**kwargs, "databases": [options["database"]]}

### Subclasses de `BaseCommand`

class AppCommand

Um comando de gerenciamento que recebe como argumento um ou mais “labels” de aplicação instaladas, e faz alguma coisa com cada um deles.

Melhor que implementar `handle()`, as subclasses devem implementar :meth:` ~AppCommand.handle_app_config`, o qual será chamado uma vez para cada aplicação.

AppCommand.handle_app_config(app_config, **options)

  Executar ações do comando para `app_config`, o qual será uma instância de `AppConfig` correspondente a um label do aplicativo informado na linha de comando.

class LabelCommand

Um comando de gestão que recebe um ou mais argumentos arbitrários (“labels”) na linha de comando, e faz alguma coisa com cada um deles.

Em vez de implementar `handle()`, subclasses devem implementar `handle_label()`, que será chamado uma vez para cada etiqueta.

LabelCommand.label

  Uma string que descreve os argumentos arbitrários passados para o comando. A string é usada no texto de uso e mensagens de erro do comando. Padrão para `` ‘label’``.

LabelCommand.handle_label(label, **options)

  Executar ações do comando para `label`, que será a string como informada na linha de comando.

### Exceções de comando

exception CommandError(returncode=1)

A classe de exceção indica um problema ao executar um comando de gestão.

Se esta exceção for gerada durante a execução de um comando de gerenciamento a partir de um console de linha de comando, ela será capturada e transformada em uma mensagem de erro bem impressa para o fluxo de saída apropriado (ou seja, `stderr`); como resultado, levantar essa exceção (com uma descrição sensata do erro) é a maneira preferida de indicar que algo deu errado na execução de um comando. Ele aceita o argumento opcional `returncode` para personalizar o status de saída para o comando de gerenciamento sair, usando `sys.exit()`.

Se um comando de gestão é chamado do código através do `call_command()`, cabe a você capturar a exceção quando necessário.