"""Namespaced Django command."""
import inspect
import os
import sqlalchemy as sa
from django.core.management.base import BaseCommand, CommandParser
[docs]class NamespacedCommand(BaseCommand):
"""Namespaced django command implementation."""
@property
def commands(self):
"""Returns the subcommands in the namespace."""
if not hasattr(self, "_commands"):
self._commands = {}
for _ in reversed(self.__class__.mro()):
self._commands.update(
{
name: cmd_cls
for name, cmd_cls in vars(self.__class__).items()
if inspect.isclass(cmd_cls) and hasattr(cmd_cls, "mro") and BaseCommand in cmd_cls.mro()
}
)
return self._commands
[docs] def run_command_from_argv(self, command, argv):
"""Runs the subcommand with namespace adjusted argv."""
command.style = self.style
cmd_args = argv[:]
cmd_args[0] = " ".join([cmd_args[0], cmd_args.pop(1)])
command.run_from_argv(cmd_args)
[docs] def run_from_argv(self, argv):
self._called_from_command_line = True
if len(argv) > 2 and not argv[2].startswith("-") and argv[2] in self.commands:
command = self.commands.get(argv[2])(stdout=self.stdout, stderr=self.stderr)
self.run_command_from_argv(command, argv)
else:
self.print_help(argv[0], argv[1])
[docs] def create_parser(self, prog_name, subcommand):
# for django<2.1 compat, filter kwargs
args = sa.util.get_cls_kwargs(CommandParser)
kwargs = {
"cmd": None,
"prog": f"{os.path.basename(prog_name)} {subcommand}",
"description": self.help or None,
}
parser = CommandParser(**{k: v for k, v in kwargs.items() if k in args})
for name, command_cls in self.commands.items():
parser.add_argument(name, help=command_cls.help)
return parser
[docs] def print_help(self, prog_name, subcommand):
parser = self.create_parser(prog_name, subcommand)
parser.print_help(self.stdout)