Escrevendo comandos personalizados do django-adminLink para este cabeçalho
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.
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:
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.
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))
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 opcionaisLink para este cabeçalho
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()
# ...
A opção (delete no nosso exemplo) está disponível no parâmetro dict (options) do método handle. Veja argparse na documentação do Python para saber mais sobre o uso do add_argument.
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 localidadesLink para este cabeçalho
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.
TestandoLink para este cabeçalho
Informações sobre como testar comandos de gerenciamento personalizados pode ser encontradas na documentação de teste.
Sobrescrevendo comandos.Link para este cabeçalho
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 CommandLink para este cabeçalho
- class BaseCommandLink para esta definição
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().
AtributosLink para este cabeçalho
Todos os atributos podem ser definidos em sua classe derivada e podem ser usados nas subclasses de BaseCommand
- BaseCommand.helpLink para esta definição
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_messageLink para esta definição
Se o seu comando define argumentos posicionais obrigatórios, você pode personalizar a mensagem de erro devolvida em caso de falta de argumentos. O padrão é a saída por
argparse(“poucos argumentos”).
- BaseCommand.output_transactionLink para esta definição
Um booleano que indica como os comandos retornam SQL “statements”; Se
True, a saída será automaticamente envolvido comBEGIN;eCOMMIT;. O valor padrão éFalse.
- BaseCommand.requires_migrations_checksLink para esta definição
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_checksLink para esta definição
A list or tuple of tags, e.g.
[Tags.staticfiles, Tags.models]. System checks registered in the chosen tags will be checked for errors prior to executing the command. The value'__all__'can be used to specify that all system checks should be performed. Default value is'__all__'.
- BaseCommand.styleLink para esta definição
Um atributo de instância que ajuda a criar uma saída colorida quando se escreve no
stdoutoustderr. 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-colorao executar o seu comando, todas as chamadasself.style()retornarão a string original sem colorir.
MétodosLink para este cabeçalho
BaseCommand tem alguns métodos que podem ser sobrescritos mas apenas o método handle() deve ser implementado.
- BaseCommand.create_parser(prog_name, subcommand, **kwargs)Link para esta definição
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()comkwargsda classe:~argparse.ArgumentParser como parâmetro.
- BaseCommand.add_arguments(parser)Link para esta definição
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 deBaseCommand.
- BaseCommand.get_version()Link para esta definição
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)Link para esta definição
Tenta executar este comando, realizando verificações de sistemas se necessário (como controlado pelo atributo
requires_system_checks). Se o comando gerar umCommandError, este é interceptado e impresso no stderr.
- BaseCommand.handle(*args, **options)Link para esta definição
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)Link para esta definição
Usa a estrutura de verificação do sistema para inspecionar todo o projeto Django para os potenciais problemas. Graves problemas são levantados como
CommandError; avisos são enviados para stderr; notificações menos importantes são enviados para stdout.Se ambos
app_configsetagsforemNone, todas as verificações do sistema são realizadas. `` Tags`` pode ser uma lista tags de checagem, comocompatibilityoumodels.
Subclasses de BaseCommandLink para este cabeçalho
- class AppCommandLink para esta definição
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)Link para esta definição
Executar ações do comando para
app_config, o qual será uma instância deAppConfigcorrespondente a um label do aplicativo informado na linha de comando.
- class LabelCommandLink para esta definição
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.labelLink para esta definição
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)Link para esta definição
Executar ações do comando para
label, que será a string como informada na linha de comando.
Exceções de comandoLink para este cabeçalho
- exception CommandError(returncode=1)Link para esta definição
A classe de exceção indica um problema ao executar um comando de gestão.
If this exception is raised during the execution of a management command from a
command line console, it will be caught and turned into a nicely-printed error
message to the appropriate output stream (i.e., stderr); as a result, raising
this exception (with a sensible description of the error) is the preferred way
to indicate that something has gone wrong in the execution of a command. It
accepts the optional returncode argument to customize the exit status for
the management command to exit with, using 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.