Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added the ability for end users to register commands with management.py.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5923 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6ad0a0188741f80c6dafef3aec62c3b2c46b7812 1 parent 7969c1b
Russell Keith-Magee freakboy3742 authored
Showing with 45 additions and 7 deletions.
  1. +45 −7 django/core/management/__init__.py
52 django/core/management/__init__.py
View
@@ -7,13 +7,25 @@
# For backwards compatibility: get_version() used to be in this module.
get_version = django.get_version
-def load_command_class(name):
+def find_commands(path):
+ """
+ Given a path to a management directory, return a list of all the command names
+ that are available. Returns an empty list if no commands are defined.
+ """
+ command_dir = os.path.join(path, 'commands')
+ try:
+ return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
+ except OSError:
+ return []
+
+def load_command_class(module, name):
"""
Given a command name, returns the Command class instance. Raises
- ImportError if it doesn't exist.
+ Raises ImportError if a command module doesn't exist, or AttributeError
+ if a command module doesn't include .
"""
- # Let the ImportError propogate.
- return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
+ # Let any errors propogate.
+ return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')()
def call_command(name, *args, **options):
"""
@@ -48,9 +60,8 @@ def default_commands(self):
The dictionary is in the format {name: command_instance}.
"""
- command_dir = os.path.join(__path__[0], 'commands')
- names = [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
- return dict([(name, load_command_class(name)) for name in names])
+ return dict([(name, load_command_class('django.core',name))
+ for name in find_commands(__path__[0])])
def usage(self):
"""
@@ -144,6 +155,33 @@ def __init__(self, project_directory):
from django.core.management.commands.startapp import ProjectCommand
self.commands['startapp'] = ProjectCommand(project_directory)
+ def default_commands(self):
+ """
+ Returns a dictionary of instances of all available Command classes.
+
+ This works by looking for and loading all Python modules in the
+ django.core.management.commands package. It also looks for a
+ management.commands package in each installed application -- if
+ a commands package exists, it loads all commands in that application.
+
+ The dictionary is in the format {name: command_instance}.
+ """
+ from django.db import models
+
+ # Base command set
+ commands = super(ProjectManagementUtility, self).default_commands()
+
+ # Get commands from all installed apps
+ for app in models.get_apps():
+ try:
+ app_name = '.'.join(app.__name__.split('.')[:-1])
+ path = os.path.join(os.path.dirname(app.__file__),'management')
+ commands.update(dict([(name, load_command_class(app_name,name)) for name in find_commands(path)]))
+ except AttributeError:
+ sys.stderr.write("Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name))
+ sys.exit(1)
+ return commands
+
def setup_environ(settings_mod):
"""
Configure the runtime environment. This can also be used by external
Please sign in to comment.
Something went wrong with that request. Please try again.