9 from optparse import make_option, OptionParser |
9 from optparse import make_option, OptionParser |
10 |
10 |
11 import django |
11 import django |
12 from django.core.exceptions import ImproperlyConfigured |
12 from django.core.exceptions import ImproperlyConfigured |
13 from django.core.management.color import color_style |
13 from django.core.management.color import color_style |
14 |
14 from django.utils.encoding import smart_str |
15 try: |
|
16 set |
|
17 except NameError: |
|
18 from sets import Set as set # For Python 2.3 |
|
19 |
15 |
20 class CommandError(Exception): |
16 class CommandError(Exception): |
21 """ |
17 """ |
22 Exception class indicating a problem while executing a management |
18 Exception class indicating a problem while executing a management |
23 command. |
19 command. |
26 command, it will be caught and turned into a nicely-printed error |
22 command, it will be caught and turned into a nicely-printed error |
27 message to the appropriate output stream (i.e., stderr); as a |
23 message to the appropriate output stream (i.e., stderr); as a |
28 result, raising this exception (with a sensible description of the |
24 result, raising this exception (with a sensible description of the |
29 error) is the preferred way to indicate that something has gone |
25 error) is the preferred way to indicate that something has gone |
30 wrong in the execution of a command. |
26 wrong in the execution of a command. |
31 |
27 |
32 """ |
28 """ |
33 pass |
29 pass |
34 |
30 |
35 def handle_default_options(options): |
31 def handle_default_options(options): |
36 """ |
32 """ |
37 Include any default options that all commands should accept here |
33 Include any default options that all commands should accept here |
38 so that ManagementUtility can handle them before searching for |
34 so that ManagementUtility can handle them before searching for |
39 user commands. |
35 user commands. |
40 |
36 |
41 """ |
37 """ |
42 if options.settings: |
38 if options.settings: |
43 os.environ['DJANGO_SETTINGS_MODULE'] = options.settings |
39 os.environ['DJANGO_SETTINGS_MODULE'] = options.settings |
44 if options.pythonpath: |
40 if options.pythonpath: |
45 sys.path.insert(0, options.pythonpath) |
41 sys.path.insert(0, options.pythonpath) |
81 all of their logic in ``handle()``, or perform some additional |
77 all of their logic in ``handle()``, or perform some additional |
82 parsing work in ``handle()`` and then delegate from it to more |
78 parsing work in ``handle()`` and then delegate from it to more |
83 specialized methods as needed. |
79 specialized methods as needed. |
84 |
80 |
85 Several attributes affect behavior at various steps along the way: |
81 Several attributes affect behavior at various steps along the way: |
86 |
82 |
87 ``args`` |
83 ``args`` |
88 A string listing the arguments accepted by the command, |
84 A string listing the arguments accepted by the command, |
89 suitable for use in help messages; e.g., a command which takes |
85 suitable for use in help messages; e.g., a command which takes |
90 a list of application names might set this to '<appname |
86 a list of application names might set this to '<appname |
91 appname ...>'. |
87 appname ...>'. |
115 performed prior to executing the command. Default value is |
111 performed prior to executing the command. Default value is |
116 ``True``. To validate an individual application's models |
112 ``True``. To validate an individual application's models |
117 rather than all applications' models, call |
113 rather than all applications' models, call |
118 ``self.validate(app)`` from ``handle()``, where ``app`` is the |
114 ``self.validate(app)`` from ``handle()``, where ``app`` is the |
119 application's Python module. |
115 application's Python module. |
120 |
116 |
121 """ |
117 """ |
122 # Metadata about this command. |
118 # Metadata about this command. |
123 option_list = ( |
119 option_list = ( |
124 make_option('-v', '--verbosity', action='store', dest='verbosity', default='1', |
120 make_option('-v', '--verbosity', action='store', dest='verbosity', default='1', |
125 type='choice', choices=['0', '1', '2'], |
121 type='choice', choices=['0', '1', '2'], |
145 def get_version(self): |
141 def get_version(self): |
146 """ |
142 """ |
147 Return the Django version, which should be correct for all |
143 Return the Django version, which should be correct for all |
148 built-in Django commands. User-supplied commands should |
144 built-in Django commands. User-supplied commands should |
149 override this method. |
145 override this method. |
150 |
146 |
151 """ |
147 """ |
152 return django.get_version() |
148 return django.get_version() |
153 |
149 |
154 def usage(self, subcommand): |
150 def usage(self, subcommand): |
155 """ |
151 """ |
156 Return a brief description of how to use this command, by |
152 Return a brief description of how to use this command, by |
157 default from the attribute ``self.help``. |
153 default from the attribute ``self.help``. |
158 |
154 |
159 """ |
155 """ |
160 usage = '%%prog %s [options] %s' % (subcommand, self.args) |
156 usage = '%%prog %s [options] %s' % (subcommand, self.args) |
161 if self.help: |
157 if self.help: |
162 return '%s\n\n%s' % (usage, self.help) |
158 return '%s\n\n%s' % (usage, self.help) |
163 else: |
159 else: |
165 |
161 |
166 def create_parser(self, prog_name, subcommand): |
162 def create_parser(self, prog_name, subcommand): |
167 """ |
163 """ |
168 Create and return the ``OptionParser`` which will be used to |
164 Create and return the ``OptionParser`` which will be used to |
169 parse the arguments to this command. |
165 parse the arguments to this command. |
170 |
166 |
171 """ |
167 """ |
172 return OptionParser(prog=prog_name, |
168 return OptionParser(prog=prog_name, |
173 usage=self.usage(subcommand), |
169 usage=self.usage(subcommand), |
174 version=self.get_version(), |
170 version=self.get_version(), |
175 option_list=self.option_list) |
171 option_list=self.option_list) |
176 |
172 |
177 def print_help(self, prog_name, subcommand): |
173 def print_help(self, prog_name, subcommand): |
178 """ |
174 """ |
179 Print the help message for this command, derived from |
175 Print the help message for this command, derived from |
180 ``self.usage()``. |
176 ``self.usage()``. |
181 |
177 |
182 """ |
178 """ |
183 parser = self.create_parser(prog_name, subcommand) |
179 parser = self.create_parser(prog_name, subcommand) |
184 parser.print_help() |
180 parser.print_help() |
185 |
181 |
186 def run_from_argv(self, argv): |
182 def run_from_argv(self, argv): |
187 """ |
183 """ |
188 Set up any environment changes requested (e.g., Python path |
184 Set up any environment changes requested (e.g., Python path |
189 and Django settings), then run this command. |
185 and Django settings), then run this command. |
190 |
186 |
191 """ |
187 """ |
192 parser = self.create_parser(argv[0], argv[1]) |
188 parser = self.create_parser(argv[0], argv[1]) |
193 options, args = parser.parse_args(argv[2:]) |
189 options, args = parser.parse_args(argv[2:]) |
194 handle_default_options(options) |
190 handle_default_options(options) |
195 self.execute(*args, **options.__dict__) |
191 self.execute(*args, **options.__dict__) |
199 Try to execute this command, performing model validation if |
195 Try to execute this command, performing model validation if |
200 needed (as controlled by the attribute |
196 needed (as controlled by the attribute |
201 ``self.requires_model_validation``). If the command raises a |
197 ``self.requires_model_validation``). If the command raises a |
202 ``CommandError``, intercept it and print it sensibly to |
198 ``CommandError``, intercept it and print it sensibly to |
203 stderr. |
199 stderr. |
204 |
200 |
205 """ |
201 """ |
206 # Switch to English, because django-admin.py creates database content |
202 # Switch to English, because django-admin.py creates database content |
207 # like permissions, and those shouldn't contain any translations. |
203 # like permissions, and those shouldn't contain any translations. |
208 # But only do this if we can assume we have a working settings file, |
204 # But only do this if we can assume we have a working settings file, |
209 # because django.utils.translation requires settings. |
205 # because django.utils.translation requires settings. |
212 from django.utils import translation |
208 from django.utils import translation |
213 translation.activate('en-us') |
209 translation.activate('en-us') |
214 except ImportError, e: |
210 except ImportError, e: |
215 # If settings should be available, but aren't, |
211 # If settings should be available, but aren't, |
216 # raise the error and quit. |
212 # raise the error and quit. |
217 sys.stderr.write(self.style.ERROR(str('Error: %s\n' % e))) |
213 sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) |
218 sys.exit(1) |
214 sys.exit(1) |
219 try: |
215 try: |
220 if self.requires_model_validation: |
216 if self.requires_model_validation: |
221 self.validate() |
217 self.validate() |
222 output = self.handle(*args, **options) |
218 output = self.handle(*args, **options) |
228 print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) |
224 print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) |
229 print output |
225 print output |
230 if self.output_transaction: |
226 if self.output_transaction: |
231 print self.style.SQL_KEYWORD("COMMIT;") |
227 print self.style.SQL_KEYWORD("COMMIT;") |
232 except CommandError, e: |
228 except CommandError, e: |
233 sys.stderr.write(self.style.ERROR(str('Error: %s\n' % e))) |
229 sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) |
234 sys.exit(1) |
230 sys.exit(1) |
235 |
231 |
236 def validate(self, app=None, display_num_errors=False): |
232 def validate(self, app=None, display_num_errors=False): |
237 """ |
233 """ |
238 Validates the given app, raising CommandError for any errors. |
234 Validates the given app, raising CommandError for any errors. |
239 |
235 |
240 If app is None, then this will validate all installed apps. |
236 If app is None, then this will validate all installed apps. |
241 |
237 |
242 """ |
238 """ |
243 from django.core.management.validation import get_validation_errors |
239 from django.core.management.validation import get_validation_errors |
244 try: |
240 try: |
245 from cStringIO import StringIO |
241 from cStringIO import StringIO |
246 except ImportError: |
242 except ImportError: |
256 |
252 |
257 def handle(self, *args, **options): |
253 def handle(self, *args, **options): |
258 """ |
254 """ |
259 The actual logic of the command. Subclasses must implement |
255 The actual logic of the command. Subclasses must implement |
260 this method. |
256 this method. |
261 |
257 |
262 """ |
258 """ |
263 raise NotImplementedError() |
259 raise NotImplementedError() |
264 |
260 |
265 class AppCommand(BaseCommand): |
261 class AppCommand(BaseCommand): |
266 """ |
262 """ |
267 A management command which takes one or more installed application |
263 A management command which takes one or more installed application |
268 names as arguments, and does something with each of them. |
264 names as arguments, and does something with each of them. |
269 |
265 |
270 Rather than implementing ``handle()``, subclasses must implement |
266 Rather than implementing ``handle()``, subclasses must implement |
271 ``handle_app()``, which will be called once for each application. |
267 ``handle_app()``, which will be called once for each application. |
272 |
268 |
273 """ |
269 """ |
274 args = '<appname appname ...>' |
270 args = '<appname appname ...>' |
275 |
271 |
276 def handle(self, *app_labels, **options): |
272 def handle(self, *app_labels, **options): |
277 from django.db import models |
273 from django.db import models |
291 def handle_app(self, app, **options): |
287 def handle_app(self, app, **options): |
292 """ |
288 """ |
293 Perform the command's actions for ``app``, which will be the |
289 Perform the command's actions for ``app``, which will be the |
294 Python module corresponding to an application name given on |
290 Python module corresponding to an application name given on |
295 the command line. |
291 the command line. |
296 |
292 |
297 """ |
293 """ |
298 raise NotImplementedError() |
294 raise NotImplementedError() |
299 |
295 |
300 class LabelCommand(BaseCommand): |
296 class LabelCommand(BaseCommand): |
301 """ |
297 """ |
306 Rather than implementing ``handle()``, subclasses must implement |
302 Rather than implementing ``handle()``, subclasses must implement |
307 ``handle_label()``, which will be called once for each label. |
303 ``handle_label()``, which will be called once for each label. |
308 |
304 |
309 If the arguments should be names of installed applications, use |
305 If the arguments should be names of installed applications, use |
310 ``AppCommand`` instead. |
306 ``AppCommand`` instead. |
311 |
307 |
312 """ |
308 """ |
313 args = '<label label ...>' |
309 args = '<label label ...>' |
314 label = 'label' |
310 label = 'label' |
315 |
311 |
316 def handle(self, *labels, **options): |
312 def handle(self, *labels, **options): |
326 |
322 |
327 def handle_label(self, label, **options): |
323 def handle_label(self, label, **options): |
328 """ |
324 """ |
329 Perform the command's actions for ``label``, which will be the |
325 Perform the command's actions for ``label``, which will be the |
330 string as given on the command line. |
326 string as given on the command line. |
331 |
327 |
332 """ |
328 """ |
333 raise NotImplementedError() |
329 raise NotImplementedError() |
334 |
330 |
335 class NoArgsCommand(BaseCommand): |
331 class NoArgsCommand(BaseCommand): |
336 """ |
332 """ |
339 Rather than implementing ``handle()``, subclasses must implement |
335 Rather than implementing ``handle()``, subclasses must implement |
340 ``handle_noargs()``; ``handle()`` itself is overridden to ensure |
336 ``handle_noargs()``; ``handle()`` itself is overridden to ensure |
341 no arguments are passed to the command. |
337 no arguments are passed to the command. |
342 |
338 |
343 Attempting to pass arguments will raise ``CommandError``. |
339 Attempting to pass arguments will raise ``CommandError``. |
344 |
340 |
345 """ |
341 """ |
346 args = '' |
342 args = '' |
347 |
343 |
348 def handle(self, *args, **options): |
344 def handle(self, *args, **options): |
349 if args: |
345 if args: |
351 return self.handle_noargs(**options) |
347 return self.handle_noargs(**options) |
352 |
348 |
353 def handle_noargs(self, **options): |
349 def handle_noargs(self, **options): |
354 """ |
350 """ |
355 Perform this command's actions. |
351 Perform this command's actions. |
356 |
352 |
357 """ |
353 """ |
358 raise NotImplementedError() |
354 raise NotImplementedError() |
359 |
355 |
360 def copy_helper(style, app_or_project, name, directory, other_name=''): |
356 def copy_helper(style, app_or_project, name, directory, other_name=''): |
361 """ |
357 """ |