Django

Code

Ticket #5222: __init__.py.2.diff

File __init__.py.2.diff, 10.4 kB (added by dnordberg@gmail.com, 1 year ago)

Diff file of init.py with last line removed.

  • __init__.py

    old new  
    11import django 
    22from optparse import OptionParser 
    33import os 
    44import sys 
    55import textwrap 
    66 
    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    from django.db import models 
     47     
     48    # Get commands from all installed apps 
     49    for app in models.get_apps(): 
     50        try: 
     51            app_name = '.'.join(app.__name__.split('.')[:-1]) 
     52            path = os.path.join(os.path.dirname(app.__file__),'management') 
     53            commands.update(dict([(name, getattr(__import__('%s.management.commands.%s' % (app_name, name), {}, {}, ['Command']), 'Command')()) for name in find_commands(path)])) 
     54        except AttributeError: 
     55            sys.stderr.write("Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name)) 
     56            sys.exit(1) 
     57             
     58    return commands 
    1759 
    1860def call_command(name, *args, **options): 
    1961    """ 
    2062    Calls the given command, with the given options and args/kwargs. 
    2163     
    2264    This is the primary API you should use for calling specific commands. 
    2365     
    2466    Some examples: 
    2567        call_command('syncdb') 
    2668        call_command('shell', plain=True) 
    2769        call_command('sqlall', 'myapp') 
    2870    """ 
    29     klass = load_command_class(name
     71    klass = getattr(__import__(_DJANGO_COMMANDS[name].__module__, {}, {}, ['Command']), 'Command')(
    3072    return klass.execute(*args, **options) 
    3173 
    3274class ManagementUtility(object): 
    3375    """ 
    3476    Encapsulates the logic of the django-admin.py and manage.py utilities. 
    3577 
    3678    A ManagementUtility has a number of commands, which can be manipulated 
    3779    by editing the self.commands dictionary. 
    3880    """ 
    3981    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  
     82        self.commands = _DJANGO_COMMANDS 
     83         
    5584    def usage(self): 
    5685        """ 
    5786        Returns a usage string, for use with optparse. 
    5887 
    5988        The string doesn't include the options (e.g., "--verbose"), because 
    6089        optparse puts those in automatically. 
    6190        """ 
    6291        usage = ["%prog command [options]\nactions:"] 
    6392        commands = self.commands.items() 
    6493        commands.sort() 
    6594        for name, cmd in commands: 
    6695            usage.append('  %s %s' % (name, cmd.args)) 
    6796            usage.extend(textwrap.wrap(cmd.help, initial_indent='    ', subsequent_indent='    ')) 
    6897            usage.append('') 
    6998        return '\n'.join(usage[:-1]) # Cut off the last list element, an empty space. 
    7099 
    71100    def execute(self, argv=None): 
    72101        """ 
    73102        Parses the given argv from the command line, determines which command 
    74103        to run and runs the command. 
    75104        """ 
    76105        if argv is None: 
    77106            argv = sys.argv 
    78107 
    79108        # Create the parser object and parse the command-line args. 
    80109        # TODO: Ideally each Command class would register its own options for 
    81110        # add_option(), but we'd need to figure out how to allow for multiple 
    82111        # Commands using the same options. The optparse library gets in the way 
    83112        # by checking for conflicts: 
    84113        # http://docs.python.org/lib/optparse-conflicts-between-options.html 
    85114        parser = OptionParser(usage=self.usage(), version=get_version()) 
    86115        parser.add_option('--settings', 
    87116            help='The Python path to a settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') 
    88117        parser.add_option('--pythonpath', 
    89118            help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".') 
    90119        parser.add_option('--plain', action='store_true', dest='plain', 
    91120            help='When using "shell": Tells Django to use plain Python, not IPython.') 
    92121        parser.add_option('--noinput', action='store_false', dest='interactive', default=True, 
    93122            help='Tells Django to NOT prompt the user for input of any kind.') 
    94123        parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True, 
    95124            help='When using "runserver": Tells Django to NOT use the auto-reloader.') 
    96125        parser.add_option('--format', default='json', dest='format', 
    97126            help='Specifies the output serialization format for fixtures') 
    98127        parser.add_option('--indent', default=None, dest='indent', 
    99128            type='int', help='Specifies the indent level to use when pretty-printing output') 
    100129        parser.add_option('--verbosity', action='store', dest='verbosity', default='1', 
    101130            type='choice', choices=['0', '1', '2'], 
    102131            help='Verbosity level; 0=minimal output, 1=normal output, 2=all output') 
    103132        parser.add_option('--adminmedia', dest='admin_media_path', default='', 
    104133            help='When using "runserver": Specifies the directory from which to serve admin media.') 
    105134        options, args = parser.parse_args(argv[1:]) 
    106135 
    107136        # If the 'settings' or 'pythonpath' options were submitted, activate those. 
    108137        if options.settings: 
    109138            os.environ['DJANGO_SETTINGS_MODULE'] = options.settings 
    110139        if options.pythonpath: 
    111140            sys.path.insert(0, options.pythonpath) 
    112141 
    113142        # Run the appropriate command. 
    114143        try: 
    115144            command_name = args[0] 
    116145        except IndexError: 
    117146            sys.stderr.write("Type '%s --help' for usage.\n" % os.path.basename(argv[0])) 
    118147            sys.exit(1) 
    119148        try: 
    120149            command = self.commands[command_name] 
    121150        except KeyError: 
    122151            sys.stderr.write("Unknown command: %r\nType '%s --help' for usage.\n" % (command_name, os.path.basename(argv[0]))) 
    123152            sys.exit(1) 
    124153        command.execute(*args[1:], **options.__dict__) 
    125154 
    126155class ProjectManagementUtility(ManagementUtility): 
    127156    """ 
    128157    A ManagementUtility that is specific to a particular Django project. 
    129158    As such, its commands are slightly different than those of its parent 
    130159    class. 
    131160 
    132161    In practice, this class represents manage.py, whereas ManagementUtility 
    133162    represents django-admin.py. 
    134163    """ 
    135164    def __init__(self, project_directory): 
    136165        super(ProjectManagementUtility, self).__init__() 
    137166 
    138167        # Remove the "startproject" command from self.commands, because 
    139168        # that's a django-admin.py command, not a manage.py command. 
    140169        del self.commands['startproject'] 
    141170 
    142171        # Override the startapp command so that it always uses the 
    143172        # project_directory, not the current working directory (which is default). 
    144173        from django.core.management.commands.startapp import ProjectCommand 
    145174        self.commands['startapp'] = ProjectCommand(project_directory) 
    146175 
    147176def setup_environ(settings_mod): 
    148177    """ 
    149178    Configure the runtime environment. This can also be used by external 
    150179    scripts wanting to set up a similar environment to manage.py. 
    151180    """ 
    152181    # Add this project to sys.path so that it's importable in the conventional 
    153182    # way. For example, if this file (manage.py) lives in a directory 
    154183    # "myproject", this code would add "/path/to/myproject" to sys.path. 
    155184    project_directory, settings_filename = os.path.split(settings_mod.__file__) 
    156185    project_name = os.path.basename(project_directory) 
    157186    settings_name = os.path.splitext(settings_filename)[0] 
    158187    sys.path.append(os.path.join(project_directory, '..')) 
    159188    project_module = __import__(project_name, {}, {}, ['']) 
    160189    sys.path.pop() 
    161190 
    162191    # Set DJANGO_SETTINGS_MODULE appropriately. 
    163192    os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name) 
     193     
     194    # Update default commands with project commands for django internal  
     195    # webservers and the manage.py utility 
     196    _DJANGO_COMMANDS.update(load_project_commands()) 
     197     
    164198    return project_directory 
    165199 
    166200def execute_from_command_line(argv=None): 
    167201    """ 
    168202    A simple method that runs a ManagementUtility. 
    169203    """ 
    170204    utility = ManagementUtility() 
    171205    utility.execute(argv) 
    172206 
    173207def execute_manager(settings_mod, argv=None): 
    174208    """ 
    175209    Like execute_from_command_line(), but for use by manage.py, a 
    176210    project-specific django-admin.py utility. 
    177211    """ 
    178212    project_directory = setup_environ(settings_mod) 
    179213    utility = ProjectManagementUtility(project_directory) 
    180214    utility.execute(argv) 
     215     
     216# Add default commands to a dict 
     217_DJANGO_COMMANDS = load_default_commands() 
     218 
     219