在Django中创建管理命令

管理命令-使用manage.py脚本从命令行执行的命令。

应用程序中最常见的区域是一次或定期执行的操作,但是由于某种原因,无法通过调度程序启动这些操作。 例如,向用户发送一次性消息,从数据库检索数据,在滚动更新之前检查是否存在必要的文件和文件夹,在开发过程中快速创建模型对象等。

基础知识


在应用程序目录(必须将应用程序添加到INSTALED_APPS中)的app / management / commands子目录中创建命令。 为每个命令创建一个单独的文件。 除了以下划线开头的文件外,这些文件可从命令行使用。

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

在此示例中,zen命令将可用,但_tools将不可用。

通过从django.core.management.base.BaseCommand类继承来创建命令。 在最简单的情况下,只需重写handle函数即可。 该命令将被执行,并且其返回的结果将被打印在控制台中。

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

让我们尝试调用我们的命令:

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

帮助类的属性是在使用--help开关调用命令或错误输入命令时显示的描述。

 $ 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. 

解析参数


如我们所见,我们的团队已经接受了7个论点。

但是,如果这对我们还不够,我们想添加自己的选择怎么办? 为此,您需要在我们的类中创建add_arguments函数,在其中列出我们要传递给团队的所有参数。 通过使用带有一系列参数的parser.add_argument函数来创建每个参数。

假设我们对函数的长输出不满意,我们只希望使用-s和--short键打印Hello world:

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

使用-s开关调用时,此文件将打印Hello world。

 $ 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. ... 

让我们更详细地研究如何指定参数解析。

解析器继承自argparse.ArgumentParser,您可以在python文档的argparse库的文档中阅读有关add_argument函数采用的参数的信息。 最重要的是:

名称或标志 -名称或标签名称或列表。 我们有“ short”,“-s”和“ --short”。
行动 -如何处理参数的值。 最有趣(但不是全部)的选项如下:

存储 -保存为我们选择的值。 如果传输了几个键值对,则最后一个的值
store_const-将常量值保存在名称键中。 该常量作为const参数传递到同一add_argument函数。

例如:

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

选项中的handle函数将被传递“ my_option”:1234

store_true,store_false-上一个选项的特殊情况。 存储的是非题
append-该值将追加到列表的末尾
append_const与上一个相同,但是传递给const参数的值是appends (可以是任何对象)

nargs是参数的数量。 可能的值:整数,“?” -默认参数'*'的一个或默认值-尽可能多,并收集在列表中,'+'-至少一个,如果包含多个-收集在列表中,argparse.REMAINDER-命令行中所有剩余的参数都收集在其中。 与action = const不兼容

请注意:如果使用此参数,即使只有一个元素,命令行中的选项值也将作为列表传递。 (在这种情况下,默认值将按原样发送,而不强制转换为列表。)

default默认值。
type-将参数强制转换为指定的类型。
选择 -参数值的选项限制。 可能值的列表将传递到选择值。
required是必需的参数。
help-关于此参数的作用的描述。
dest-如果要使用其他名称保存选项,则可以指定dest ='my_new_name'。 否则,将使用参数名称。
然后,这些参数将作为选项字典传递给handle函数。

但是,如果我们要传递未命名的参数来处理该怎么办?

在这种情况下,您需要在args选项中的add_arguments中指定所有未命名参数的接收。 例如,如果我们要将几个整数传递给命令:

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

执行顺序


该命令按以下顺序执行:

  1. 首先,调用run_from_argv()方法。 该方法通过调用create_parser创建一个解析器,并且创建的解析器添加默认参数(no-color类型),还调用add_arguments方法,从而添加我们创建的所有选项。
  2. 之后,将调用execute函数。 此函数执行多项检查,然后运行handle函数。 句柄的结果将打印到标准输出。

当然,任何这些功能都可以定制。 例如,让我们绘制多行帮助消息的漂亮输出:

 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 

在大多数情况下,这就是编写管理命令所需要的。

结论


本文并不声称是创建管理命令时所有可能性的完整概述-Django文档中对此进行了描述。 那些感兴趣的可以转向
文件

there实际上,这里没有分析命令行参数。 那些希望深入研究这个问题的人应该研究python的累积量。

Argparse模块

Source: https://habr.com/ru/post/zh-CN415049/


All Articles