Django

Code

Changeset 6050

Show
Ignore:
Timestamp:
09/05/07 09:01:31 (1 year ago)
Author:
russellm
Message:

Refs #5343 -- Reverted [6047]. Loading custom commands was causing the settings file to get read before the options could be processed to determine if a --settings option was present. Back to the drawing board (again)...

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/management/__init__.py

    r6047 r6050  
    11import django 
    2 from django.core.management.base import CommandError 
    32from optparse import OptionParser 
    43import os 
     
    98get_version = django.get_version 
    109 
    11 # A cache of loaded commands, so that call_command  
    12 # doesn't have to reload every time it is called 
    13 _commands = None 
    14      
    15 def find_commands(path): 
    16     """ 
    17     Given a path to a management directory, return a list of all the command names  
    18     that are available. Returns an empty list if no commands are defined. 
    19     """ 
    20     command_dir = os.path.join(path, 'commands') 
    21     try: 
    22         return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')] 
    23     except OSError: 
    24         return [] 
    25  
    26 def load_command_class(module, name): 
     10def load_command_class(name): 
    2711    """ 
    2812    Given a command name, returns the Command class instance. Raises 
    29     Raises ImportError if a command module doesn't exist, or AttributeError 
    30     if a command module doesn't contain a Command instance. 
     13    ImportError if it doesn't exist. 
    3114    """ 
    32     # Let any errors propogate. 
    33     return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')() 
    34  
    35 def get_commands(load_user_commands=True): 
    36     """ 
    37     Returns a dictionary of instances of all available Command classes. 
    38     Core commands are always included; user-register commands will also 
    39     be included if ``load_user_commands`` is True. 
    40  
    41     This works by looking for a management.commands package in  
    42     django.core, and in each installed application -- if a commands  
    43     package exists, it loads all commands in that application. 
    44  
    45     The dictionary is in the format {name: command_instance}. 
    46      
    47     The dictionary is cached on the first call, and reused on subsequent 
    48     calls. 
    49     """ 
    50     global _commands 
    51     if _commands is None: 
    52         _commands = dict([(name, load_command_class('django.core',name))  
    53                             for name in find_commands(__path__[0])]) 
    54         if load_user_commands: 
    55             # Get commands from all installed apps 
    56             from django.db import models 
    57             for app in models.get_apps(): 
    58                 try: 
    59                     app_name = '.'.join(app.__name__.split('.')[:-1]) 
    60                     path = os.path.join(os.path.dirname(app.__file__),'management') 
    61                     _commands.update(dict([(name, load_command_class(app_name,name))  
    62                                                     for name in find_commands(path)])) 
    63                 except AttributeError: 
    64                     raise CommandError, "Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name) 
    65     return _commands 
     15    # Let the ImportError propogate. 
     16    return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')() 
    6617 
    6718def call_command(name, *args, **options): 
     
    7627        call_command('sqlall', 'myapp') 
    7728    """ 
    78     try: 
    79         command = get_commands()[name] 
    80     except KeyError: 
    81         raise CommandError, "Unknown command: %r\n" % name 
    82     return command.execute(*args, **options) 
    83      
     29    klass = load_command_class(name) 
     30    return klass.execute(*args, **options) 
     31 
    8432class ManagementUtility(object): 
    8533    """ 
     
    9038    """ 
    9139    def __init__(self): 
    92         # The base management utility doesn't expose any user-defined commands 
    93         try: 
    94             self.commands = get_commands(load_user_commands=False) 
    95         except CommandError, e: 
    96             sys.stderr.write(str(e)) 
    97             sys.exit(1) 
     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]) 
    9854 
    9955    def usage(self): 
     
    178134    """ 
    179135    def __init__(self, project_directory): 
    180         try: 
    181             self.commands = get_commands() 
    182         except CommandError, e: 
    183             sys.stderr.write(str(e)) 
    184             sys.exit(1) 
     136        super(ProjectManagementUtility, self).__init__() 
    185137 
    186138        # Remove the "startproject" command from self.commands, because 
  • django/trunk/docs/django-admin.txt

    r6047 r6050  
    620620    * Type ``sql``, then [TAB], to see all available options whose names start 
    621621      with ``sql``. 
    622  
    623 Customized actions 
    624 ================== 
    625  
    626 **New in Django development version** 
    627  
    628 If you want to add an action of your own to ``manage.py``, you can. 
    629 Simply add a ``management/commands`` directory to your application. 
    630 Each python module in that directory will be discovered and registered as 
    631 a command that can be executed as an action when you run ``manage.py``:: 
    632  
    633     /fancy_blog 
    634         __init__.py 
    635         models.py 
    636         /management 
    637             __init__.py 
    638             /commands 
    639                 __init__.py 
    640                 explode.py 
    641         views.py 
    642          
    643 In this example, ``explode`` command will be made available to any project 
    644 that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``. 
    645  
    646 The ``explode.py`` module has only one requirement -- it must define a class 
    647 called ``Command`` that extends ``django.core.management.base.BaseCommand``. 
    648  
    649 For more details on how to define your own commands, look at the code for the 
    650 existing ``django-admin.py`` commands, in ``/django/core/management/commands``.