如何在 Django 中创建自定义的管理命令

共 2310字,需浏览 5分钟

 ·

2022-03-04 01:10

用过 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 的定时任务。如果今天的分享有帮助,还请给个在看,多谢支持。

浏览 21
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报