如何在 Django 中创建自定义的管理命令
用过 Django 的朋友应该最熟悉这三个命令:
python manage.py runserver
python manage.py makemigrations
python manage.py migrate
非常方便,不是吗?那其实,我们也可以自定义这样的命令,来提高我们的开发效率。
今天就来分享如何在 Django 中创建自定义的管理命令。
和 Django 的模版 template 一样,自定义的命令也遵循一定的路径格式。
在每个 app 目录下,新建一个 management/commands 目录,Django 会给目录下的每个 Python 文件注册一个 manage.py 命令,这个命令的名字不以下划线开头。例如:
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.py
请注意,上述路径中的 _private.py 不会生效。polls 需要在 settings.py
中的 INSTALLED_APPS 中注册,python manage.py closepoll
才会生效。
接下来说下 closepoll 这个文件的格式。
对 closepoll.py 模块只有一个要求,那就是必须定义 Command 类,该类继承自 BaseCommand 或其子类。
比如像这样:
from django.core.management.base import BaseCommand, CommandError
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']:
print(f"closing {poll_id} done.")
#do something here
self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))
通常,主要的处理逻辑会放在 handle 函数里面,在 INSTALLED_APPS 中添加 polls 后,运行一下 python manage.py closepoll 1 2 3
会得到如下结果:
当你使用管理命令并希望提供控制台输出时,你需要 write 至 self.stdout 和 self.stderr,而不是直接 print 至 stdout 和 stderr,这样可以输出多彩的结果。还需要注意的是,你不需要用换行符来结束消息,它会自动添加,除非你指定了 ending 参数:
self.stdout.write("Unterminated line", ending='')
还可以为命令添加可选参数,通过接受额外的命令行选项来删除一个给定的投票,而不是关闭它。这些自定义选项可以在 add_arguments() 方法中添加,比如:
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()
# ...
本例中 delete 是由 handle 方法的 options 字典参数传入的,参见 Python 文档查询 argparse,获取更多 add_argument 的用法。
最后的话
自定义管理命令在运行独立脚本命令方面十分有用,也可用于 UNIX 的周期性 crontab 任务,或是 Windows 的定时任务。如果今天的分享有帮助,还请给个在看,多谢支持。