Ticket #5222: __init__.2.py

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

The patched version of init.py with the last line removed.

Line 
1import django
2from optparse import OptionParser
3import os
4import sys
5import textwrap
6
7# For backwards compatibility: get_version() used to be in this module.
8get_version = django.get_version
9
10def load_command_class(name):
11    """
12    Given a command name, returns the Command class instance. Raises
13    ImportError if it doesn't exist.
14    """
15    # Let the ImportError propogate.
16    return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
17
18def call_command(name, *args, **options):
19    """
20    Calls the given command, with the given options and args/kwargs.
21   
22    This is the primary API you should use for calling specific commands.
23   
24    Some examples:
25        call_command('syncdb')
26        call_command('shell', plain=True)
27        call_command('sqlall', 'myapp')
28    """
29    klass = load_command_class(name)
30    return klass.execute(*args, **options)
31
32class ManagementUtility(object):
33    """
34    Encapsulates the logic of the django-admin.py and manage.py utilities.
35
36    A ManagementUtility has a number of commands, which can be manipulated
37    by editing the self.commands dictionary.
38    """
39    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
55    def usage(self):
56        """
57        Returns a usage string, for use with optparse.
58
59        The string doesn't include the options (e.g., "--verbose"), because
60        optparse puts those in automatically.
61        """
62        usage = ["%prog command [options]\nactions:"]
63        commands = self.commands.items()
64        commands.sort()
65        for name, cmd in commands:
66            usage.append(%s %s' % (name, cmd.args))
67            usage.extend(textwrap.wrap(cmd.help, initial_indent='    ', subsequent_indent='    '))
68            usage.append('')
69        return '\n'.join(usage[:-1]) # Cut off the last list element, an empty space.
70
71    def execute(self, argv=None):
72        """
73        Parses the given argv from the command line, determines which command
74        to run and runs the command.
75        """
76        if argv is None:
77            argv = sys.argv
78
79        # Create the parser object and parse the command-line args.
80        # TODO: Ideally each Command class would register its own options for
81        # add_option(), but we'd need to figure out how to allow for multiple
82        # Commands using the same options. The optparse library gets in the way
83        # by checking for conflicts:
84        # http://docs.python.org/lib/optparse-conflicts-between-options.html
85        parser = OptionParser(usage=self.usage(), version=get_version())
86        parser.add_option('--settings',
87            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.')
88        parser.add_option('--pythonpath',
89            help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".')
90        parser.add_option('--plain', action='store_true', dest='plain',
91            help='When using "shell": Tells Django to use plain Python, not IPython.')
92        parser.add_option('--noinput', action='store_false', dest='interactive', default=True,
93            help='Tells Django to NOT prompt the user for input of any kind.')
94        parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True,
95            help='When using "runserver": Tells Django to NOT use the auto-reloader.')
96        parser.add_option('--format', default='json', dest='format',
97            help='Specifies the output serialization format for fixtures')
98        parser.add_option('--indent', default=None, dest='indent',
99            type='int', help='Specifies the indent level to use when pretty-printing output')
100        parser.add_option('--verbosity', action='store', dest='verbosity', default='1',
101            type='choice', choices=['0', '1', '2'],
102            help='Verbosity level; 0=minimal output, 1=normal output, 2=all output')
103        parser.add_option('--adminmedia', dest='admin_media_path', default='',
104            help='When using "runserver": Specifies the directory from which to serve admin media.')
105        options, args = parser.parse_args(argv[1:])
106
107        # If the 'settings' or 'pythonpath' options were submitted, activate those.
108        if options.settings:
109            os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
110        if options.pythonpath:
111            sys.path.insert(0, options.pythonpath)
112
113        # Run the appropriate command.
114        try:
115            command_name = args[0]
116        except IndexError:
117            sys.stderr.write("Type '%s --help' for usage.\n" % os.path.basename(argv[0]))
118            sys.exit(1)
119        try:
120            command = self.commands[command_name]
121        except KeyError:
122            sys.stderr.write("Unknown command: %r\nType '%s --help' for usage.\n" % (command_name, os.path.basename(argv[0])))
123            sys.exit(1)
124        command.execute(*args[1:], **options.__dict__)
125
126class ProjectManagementUtility(ManagementUtility):
127    """
128    A ManagementUtility that is specific to a particular Django project.
129    As such, its commands are slightly different than those of its parent
130    class.
131
132    In practice, this class represents manage.py, whereas ManagementUtility
133    represents django-admin.py.
134    """
135    def __init__(self, project_directory):
136        super(ProjectManagementUtility, self).__init__()
137
138        # Remove the "startproject" command from self.commands, because
139        # that's a django-admin.py command, not a manage.py command.
140        del self.commands['startproject']
141
142        # Override the startapp command so that it always uses the
143        # project_directory, not the current working directory (which is default).
144        from django.core.management.commands.startapp import ProjectCommand
145        self.commands['startapp'] = ProjectCommand(project_directory)
146
147def setup_environ(settings_mod):
148    """
149    Configure the runtime environment. This can also be used by external
150    scripts wanting to set up a similar environment to manage.py.
151    """
152    # Add this project to sys.path so that it's importable in the conventional
153    # way. For example, if this file (manage.py) lives in a directory
154    # "myproject", this code would add "/path/to/myproject" to sys.path.
155    project_directory, settings_filename = os.path.split(settings_mod.__file__)
156    project_name = os.path.basename(project_directory)
157    settings_name = os.path.splitext(settings_filename)[0]
158    sys.path.append(os.path.join(project_directory, '..'))
159    project_module = __import__(project_name, {}, {}, [''])
160    sys.path.pop()
161
162    # Set DJANGO_SETTINGS_MODULE appropriately.
163    os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
164    return project_directory
165
166def execute_from_command_line(argv=None):
167    """
168    A simple method that runs a ManagementUtility.
169    """
170    utility = ManagementUtility()
171    utility.execute(argv)
172
173def execute_manager(settings_mod, argv=None):
174    """
175    Like execute_from_command_line(), but for use by manage.py, a
176    project-specific django-admin.py utility.
177    """
178    project_directory = setup_environ(settings_mod)
179    utility = ProjectManagementUtility(project_directory)
180    utility.execute(argv)
Back to Top