跳转到主要内容

编写具有子命令的Django管理命令。

项目描述

使用django-subcommander编写具有子命令的Django管理命令,每个子命令都可以有自己独特的选项、帮助和其他通常的命令行为。子命令只是普通的Django BaseCommand 子类,因此无需学习太多新知识。以下是一个顶级命令示例;您可以将此放入应用程序的 management.commands.desserts 模块中

from django_subcommander import SubcommandDispatcher


class Command(SubcommandDispatcher):
    """The top-level "dessert" command which has several subcommands"""

    help = 'Eat, top, and do various things with desserts.'
    args = '<subcommand> [more arguments and options]'

    def _subcommand(self, name):
        """
        Return a management command that implements the subcommand of the
        given name.
        """
        if name == 'eat':
            return EatCommand()
        elif name == 'top':
            ,,,


class EatCommand(BaseCommand):
    # You could put this in another module or wherever you want.
    help = 'Eat a dessert.'
    args = '[number of bites]'

    # Add options here with make_option(), in the usual way.

    def handle(self, *args, **options):
        ...

要调用5口吃甜点的子命令……

./manage.py dessert eat 5

要查看 eat 子命令的帮助……

./manage.py dessert eat --help

要查看顶级命令的帮助……

./manage.py dessert --help

如果实现了 _subcommand_names,顶级命令的帮助将列出其子命令

class Command(SubcommandDispatcher):
    ...

    def _subcommand(self, name):
        ...

    def _subcommand_names(self):
        """Return a list of the names of all the subcommands."""
        return ['eat', 'top']

然后, ./manage.py dessert --help 将显示类似以下内容

Usage: ...

Options:
  ...

Subcommands:
  eat [number of bites]
  top <topping> [more toppings]

疯狂的东西

  • 请注意,_subcommand() 返回一个命令实例,而不是类或模块路径。这不仅给您提供了将子命令代码放置在您希望的位置的自由,而且还意味着您可以在运行时动态生成或参数化子命令。

  • 没有理由您不能让一个 SubcommandDispatcher 返回另一个,从而实现多级子命令。

设计笔记

Django的管理命令框架建立在optparse之上,而不是更现代的argparse,后者原生支持子命令。要让argparse与Django的管理命令基础设施协同工作,需要进行大量的粘合,所以我选择了简单的路径。这允许作者重用他们关于编写Django管理命令的所有现有知识。例如,我有一组现有的命令,我想要在几个子命令下组织它们。这让我避免了在management/commands下拥有数百个单独的文件;它给了我将所有这些命令代码放在其他地方并按更自然的方式组织它们的自由。将命令转换为子命令不需要对它们进行任何更改。

django-subcommander绝对是一个“糟糕的是更好的”解决方案。它是解决management/commands中文件过多的一个极其实用的解决方案。如果它变得很长且复杂,我可能会配置Django来支持基于argparse的命令……嗯,关于制作一个基于argparse的BaseCommand替代品怎么办?

未来计划

  • 测试。我现在整天都在使用它,但我只进行了“就地”测试。

  • 在顶级命令上获取--help时,显示子命令列表的更多灵活性

  • 支持Django的其他命令超类,如AppCommandLabelCommand(如果它们实际上还不工作,并且有需求的话)

  • 我短暂地走了一段让_subcommand()能够访问整个argv并且能够返回未用于分发的任何args的道路。这最终极大地增加了复杂度,但收益并不明确。如果您觉得这很有用,请提交一个错误报告。

版本历史

0.1

首次发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

django-subcommander-0.1.tar.gz (5.9 kB 查看哈希值)

上传时间 源代码

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面