Ticket #5222: __init__.py.diff

File __init__.py.diff, 4.6 KB (added by dnordberg@…, 8 years ago)

Diff file of init.py allowing end users to register management commands.

  • .py

    old new  
    77# For backwards compatibility: get_version() used to be in this module.
    88get_version = django.get_version
    99
    10 def load_command_class(name):
     10def find_commands(path):
    1111    """
    12     Given a command name, returns the Command class instance. Raises
    13     ImportError if it doesn't exist.
     12    Given a path to a management directory, return a list of all the command names
     13    that are available. Returns an empty list if no commands are defined.
    1414    """
    15     # Let the ImportError propogate.
    16     return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
     15    command_dir = os.path.join(path, 'commands')
     16    try:
     17        return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
     18    except OSError:
     19        return []
     20
     21def load_default_commands():
     22    """
     23    Returns a dictionary of instances of all available Command classes.
     24
     25    This works by looking for and loading all Python modules in the
     26    django.core.management.commands package.
     27
     28    The dictionary is in the format {name: command_instance}.
     29    """
     30    return dict([(name, getattr(__import__('django.core.management.commands.%s' % (name), {}, {}, ['Command']), 'Command')()) for name in find_commands(__path__[0])])
     31
     32def load_project_commands():
     33    """
     34    Returns a dictionary of instances of all available Command classes.
     35
     36    It looks for a management.commands package in each installed application
     37    -- if a commands package exists, it loads all commands in that
     38    application and raises an AttributeError if a command doesn't contain a
     39    Command instance.
     40
     41    The dictionary is in the format {name: command_instance}.
     42    """
     43   
     44    commands = {}
     45   
     46    if 'DJANGO_SETTINGS_MODULE' in os.environ:
     47        from django.db import models
     48       
     49        # Get commands from all installed apps
     50        for app in models.get_apps():
     51            try:
     52                app_name = '.'.join(app.__name__.split('.')[:-1])
     53                path = os.path.join(os.path.dirname(app.__file__),'management')
     54                commands.update(dict([(name, getattr(__import__('%s.management.commands.%s' % (app_name, name), {}, {}, ['Command']), 'Command')()) for name in find_commands(path)]))
     55            except AttributeError:
     56                sys.stderr.write("Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name))
     57                sys.exit(1)
     58           
     59    return commands
    1760
    1861def call_command(name, *args, **options):
    1962    """
     
    2669        call_command('shell', plain=True)
    2770        call_command('sqlall', 'myapp')
    2871    """
    29     klass = load_command_class(name)
     72    klass = getattr(__import__(_DJANGO_COMMANDS[name].__module__, {}, {}, ['Command']), 'Command')()
    3073    return klass.execute(*args, **options)
    3174
    3275class ManagementUtility(object):
     
    3780    by editing the self.commands dictionary.
    3881    """
    3982    def __init__(self):
    40         self.commands = self.default_commands()
    41 
    42     def default_commands(self):
    43         """
    44         Returns a dictionary of instances of all available Command classes.
    45 
    46         This works by looking for and loading all Python modules in the
    47         django.core.management.commands package.
    48 
    49         The dictionary is in the format {name: command_instance}.
    50         """
    51         command_dir = os.path.join(__path__[0], 'commands')
    52         names = [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
    53         return dict([(name, load_command_class(name)) for name in names])
    54 
     83        self.commands = _DJANGO_COMMANDS
     84       
    5585    def usage(self):
    5686        """
    5787        Returns a usage string, for use with optparse.
     
    161191
    162192    # Set DJANGO_SETTINGS_MODULE appropriately.
    163193    os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
     194   
     195    # Update default commands with project commands for django internal
     196    # webservers and the manage.py utility
     197    _DJANGO_COMMANDS.update(load_project_commands())
     198   
    164199    return project_directory
    165200
    166201def execute_from_command_line(argv=None):
     
    178213    project_directory = setup_environ(settings_mod)
    179214    utility = ProjectManagementUtility(project_directory)
    180215    utility.execute(argv)
     216   
     217# Add default commands to a dict
     218_DJANGO_COMMANDS = load_default_commands()
     219
     220# Update default commands with project commands
     221# when DJANGO_SETTINGS_MODULE is already set.
     222_DJANGO_COMMANDS.update(load_project_commands())
     223
Back to Top