Criando comandos de gerenciamento no Django

Comandos de gerenciamento - comandos executados na linha de comandos usando o script manage.py.

As áreas mais comuns do aplicativo são ações executadas uma vez ou periodicamente, mas para as quais a inicialização através do planejador está indisponível por algum motivo. Por exemplo, enviando mensagens únicas aos usuários, recuperando dados de um banco de dados, verificando a presença dos arquivos e pastas necessários antes de rolar as atualizações, criando rapidamente objetos de modelo durante o desenvolvimento, etc.

O básico


Os comandos são criados nos diretórios do aplicativo (os aplicativos devem ser adicionados ao INSTALED_APPS), no subdiretório app / management / command. Um arquivo separado é criado para cada comando. Os arquivos estarão disponíveis na linha de comando, exceto aqueles que começam com um sublinhado.

app/ __init__.py management/ __init__.py commands/ __init__.py _tools.py zen.py 

Neste exemplo, o comando zen estará disponível, mas _tools não.

Os comandos são criados herdando da classe django.core.management.base.BaseCommand. No caso mais simples, basta reescrever a função de manipulação. Este comando será executado e o resultado retornado por ele será impresso no console.

 from django.core.management.base import BaseCommand class Command(BaseCommand): help = 'The Zen of Python' def handle(self, *args, **options): import this 

Vamos tentar chamar nosso comando:

 python manage.py zen The Zen of Python, by Tim Peters Beautiful is better than ugly. ... 

O atributo da classe de ajuda é uma descrição que é exibida quando um comando com a opção --help é chamado ou se o comando é inserido incorretamente.

 $ python manage.py zen --help usage: manage.py zen [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] The Zen of Python optional arguments: -h, --help show this help message and exit --version show program's version number and exit -v {0,1,2,3}, --verbosity {0,1,2,3} Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output --settings SETTINGS The Python path to a settings module, eg "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath PYTHONPATH A directory to add to the Python path, eg "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions --no-color Don't colorize the command output. 

Analisando argumentos


Como podemos ver, nossa equipe já está aceitando 7 argumentos.

Mas e se isso não for suficiente para nós e quisermos adicionar nossas próprias opções? Para fazer isso, você precisa criar a função add_arguments em nossa classe, onde listar todos os argumentos que queremos passar para nossa equipe. Cada argumento é criado chamando a função parser.add_argument com uma série de parâmetros.

Suponha que não nos sintamos confortáveis ​​com a saída longa de nossa função e que apenas o Hello world seja impresso com as teclas -s e --short:

 from django.core.management.base import BaseCommand class Command(BaseCommand): help = 'The Zen of Python' def handle(self, *args, **options): if options['short']: import __hello__ else: import this def add_arguments(self, parser): parser.add_argument( '-s', '--short', action='store_true', default=False, help='  ' ) 

Este arquivo imprimirá Hello world quando chamado com a opção -s.

 $ python manage.py zen -s Hello world... (coolwriter)$ python manage.py zen The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. ... 

Vamos examinar com mais detalhes como a análise de argumentos é especificada.

O analisador é herdado de argparse.ArgumentParser e você pode ler sobre os argumentos utilizados pela função add_argument na documentação da biblioteca argparse na documentação do python. Os mais importantes são:

nome ou bandeiras - nome ou lista de nomes e etiquetas. Temos esse 'curto', '-s' e '--short'.
ação - o que fazer com o valor do argumento. As opções mais interessantes (mas não todas) são as seguintes:

armazenar - salve como o valor da nossa opção. Se vários pares de valores-chave forem transmitidos, o valor do último
store_const - salve o valor constante na chave de nome. A constante é passada como argumento const para a mesma função add_argument.

Por exemplo:

 parser.add_argument('my_option', action='store_const', const=1234) 

A função de manipulação nas opções será passada 'my_option': 1234

store_true, store_false - casos especiais da opção anterior. Verdadeiro ou falso armazenado
anexar - o valor será anexado ao final da lista
append_const é o mesmo que o anterior, mas o valor passado para o argumento const é anexado (que pode ser qualquer objeto)

nargs é o número de argumentos. Valores possíveis: inteiro, '?' - um ou o valor padrão do argumento padrão, '*' - quantos houver e são coletados em uma lista, '+' - pelo menos um e se vários - são coletados em uma lista, argparse.REMAINDER - todos os argumentos restantes da linha de comando são coletados lá . Incompatível com action = const

Observação: se você usar esse argumento, o valor da sua opção na linha de comando será passado para o tratamento como uma lista, mesmo se houver apenas um elemento. (Nesse caso, o valor padrão é transmitido como está, sem transmitir para a lista.)

o padrão é o valor padrão .
type - lança o argumento para o tipo especificado.
escolhas - restrição de variantes do valor do argumento. Uma lista de valores possíveis é passada para o valor de opções.
required é um argumento obrigatório.
help - Uma descrição do que esse argumento faz.
dest - se quiser salvar sua opção com um nome diferente, você pode especificar dest = 'meu_novo_nome'. Caso contrário, o nome do argumento será usado.
Esses argumentos serão passados ​​para a função handle como um dicionário de opções.

Mas e se quisermos passar argumentos sem nome para lidar?

Nesse caso, você precisa especificar em add_arguments o recebimento de todos os argumentos não nomeados na opção args. Por exemplo, se queremos passar vários números inteiros para o comando:

 def add_arguments(self, parser): parser.add_argument( nargs='+', type=int, dest = 'args' ) 

Ordem de execução


O comando é executado na seguinte ordem:

  1. Primeiro, o método run_from_argv () é chamado. Esse método cria um analisador por meio de uma chamada para create_parser, e o analisador criado adiciona argumentos padrão (do tipo sem cor) e também chama o método add_arguments, adicionando todas as opções que criamos.
  2. Depois disso, a função de execução é chamada. Esta função executa várias verificações e, em seguida, executa a função de manipulação. O resultado da alça é impresso na saída padrão.

Obviamente, qualquer uma dessas funções pode ser personalizada. Por exemplo, vamos desenhar a bela saída de uma mensagem de ajuda com várias linhas:

 from argparse import RawTextHelpFormatter def create_parser(self, prog_name, subcommand): parser = super(Command, self).create_parser(prog_name, subcommand) parser.formatter_class = RawTextHelpFormatter return parser 

Provavelmente, é tudo o que é necessário para escrever comandos de gerenciamento na maioria dos casos.

Conclusão


O artigo não afirma ser uma visão geral completa de todas as possibilidades ao criar comandos de gerenciamento - eles são descritos na documentação do Django. Os interessados ​​podem recorrer a
documentação .

A análise de argumentos de linha de comando, aliás, praticamente não é divulgada. Aqueles que desejam mergulhar nos meandros dessa edição devem estudar a acumulação de python.

Módulo Argparse

Source: https://habr.com/ru/post/pt415049/


All Articles