Django Command

  编写自定义 django-admin 命令 

    应用程序可以使用manage.py命令注册自己的操作。

    在项目中添加 management/commands 目录,Django将为该目录中名称不以下划线开头的每个Python模块注册一个mange.py命令。

    如在polls应用下构建一个自定义的custom_command命令,目录结构如下:

polls/
    __init__.py
    models.py
    management/
        commands/
            _private.py
            custom_command.py
    tests.py
    views.py

     在这个例子中,任何在settings.py 中的 INSTALLED_APPS 中包含 polls 应用程序的项目都可以使用 closepoll 命令

     custom_command.py 模块只有一个要求——它必须定义一个类名为Command 并且继承 BaseCommand类 或BaseCommand的子类。

    custom_command.py内容如下:

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_id', nargs='+', type=int)

    def handle(self, *args, **options):
        for poll_id in options['poll_id']:
            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))

 

    执行自定义命令:

python manage.py 命令名(不带 .py后缀)
# 如
python manage.py custom_command

    会自动执行命令的handle()方法

 

 

    命令的可选参数 

     自定义的选项可以像如下方式添加到 add_arguments() 方法中

class Command(BaseCommand):
    def add_arguments(self, parser):
        # Positional arguments
        parser.add_argument('poll_id', nargs='+', type=int)

        # Named (optional) arguments
        parser.add_argument(
            '--delete',
            action='store_true',
            dest='delete',
            help='Delete poll instead of closing it',
        )

    def handle(self, *args, **options):
        # ...
        if options['delete']:
            poll.delete()
        # ...

  获取参数 option['poll_id']  

  带自定义参数的启动命令:

  python manage.py custom_command poll_id=xxx --delete

 

 

    BaseCommand方法

      BaseCommand 有一些可以被重写的方法,但只有 handle() 方法子类必须要实现。

      注意:如果继承了BaseCommand并实现了 __init__ 方法,那么必须在实现的 __init__ 中调用BaseCommand类的__init__方法

class Command(BaseCommand):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # ...

      ①:add_arguments(self, parser) 方法

        添加解析器参数以处理传递给命令的命令行参数的入口点。自定义命令应覆盖此方法以添加命令接受的位置参数和可选参数。直接继承 BaseCommand 时不需要调用 super()

        ②:get_version(self) 

        返回 Django 版本,它应该对所有内置 Django 命令都是正确的。用户提供的命令可以覆盖此方法以返回自己的版本

      ③:execute(self, *args, **options)

        尝试执行此命令,并在需要时执行系统检查(由 requires_system_checks 属性控制)。如果命令引发 CommandError,它会被拦截并打印到 stderr    

        注意:不应直接从您的代码中调用 execute() 来执行命令。请改用 call_command()

      ④:handle(self, *args, **options)

        命令的实际逻辑。子类必须实现此方法。

        它可能会返回一个字符串,该字符串将被打印到标准输出(由 BEGIN 包装;如果 output_transaction 为 True,则由 COMMIT 包装)

       ⑤:check(self, app_configs=None, tags=None, display_num_errors=False,include_deployment_checks=False, fail_level=checks.ERROR)

        使用系统检查框架检查整个 Django 项目是否存在潜在问题。严重问题作为 CommandError 提出;警告输出到标准错误;次要通知输出到标准输出。

        如果 app_configs 和 tags 都为 None,则执行所有系统检查。标签可以是检查标签列表,例如兼容性或型号

    

 

 

 

附录:

  官方文档:https://docs.djangoproject.com/en/2.1/howto/custom-management-commands/

 

 

 

END.

posted @ 2022-01-19 10:59  杨岂  阅读(420)  评论(0编辑  收藏  举报