Ticket #5222: __init__.2.py

File __init__.2.py, 7.7 KB (added by dnordberg@…, 17 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