Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5943 -- Modified django-admin to behave like manage.py if sett…

…ings are provided, either as --settings or DJANGO_SETTINGS_MODULE. Thanks to Joseph Kocherhans and Todd O'Bryan for their work on this ticket.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8282 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ec7d8b7c6147397fd689ee9538801bd0df59d73a 1 parent 7610983
Russell Keith-Magee authored August 10, 2008
58  django/core/management/__init__.py
@@ -66,7 +66,7 @@ class instance. All errors raised by the import process
66 66
     return getattr(__import__('%s.management.commands.%s' % (app_name, name),
67 67
                    {}, {}, ['Command']), 'Command')()
68 68
 
69  
-def get_commands(load_user_commands=True, project_directory=None):
  69
+def get_commands():
70 70
     """
71 71
     Returns a dictionary mapping command names to their callback applications.
72 72
 
@@ -77,7 +77,7 @@ def get_commands(load_user_commands=True, project_directory=None):
77 77
     Core commands are always included. If a settings module has been
78 78
     specified, user-defined commands will also be included, the
79 79
     startproject command will be disabled, and the startapp command
80  
-    will be modified to use the directory in which that module appears.
  80
+    will be modified to use the directory in which the settings module appears.
81 81
 
82 82
     The dictionary is in the format {command_name: app_name}. Key-value
83 83
     pairs from this dictionary can then be used in calls to
@@ -94,15 +94,28 @@ def get_commands(load_user_commands=True, project_directory=None):
94 94
     if _commands is None:
95 95
         _commands = dict([(name, 'django.core') for name in find_commands(__path__[0])])
96 96
 
97  
-        if load_user_commands:
98  
-            # Get commands from all installed apps.
  97
+        # Find the installed apps
  98
+        try:
  99
+            from django.conf import settings
  100
+            apps = settings.INSTALLED_APPS
  101
+        except (AttributeError, EnvironmentError, ImportError):
  102
+            apps = []
  103
+
  104
+        # Find the project directory
  105
+        try:
99 106
             from django.conf import settings
100  
-            for app_name in settings.INSTALLED_APPS:
101  
-                try:
102  
-                    path = find_management_module(app_name)
103  
-                    _commands.update(dict([(name, app_name) for name in find_commands(path)]))
104  
-                except ImportError:
105  
-                    pass # No management module -- ignore this app.
  107
+            project_directory = setup_environ(__import__(settings.SETTINGS_MODULE))
  108
+        except (AttributeError, EnvironmentError, ImportError):
  109
+            project_directory = None
  110
+
  111
+        # Find and load the management module for each installed app.
  112
+        for app_name in apps:
  113
+            try:
  114
+                path = find_management_module(app_name)
  115
+                _commands.update(dict([(name, app_name)
  116
+                                       for name in find_commands(path)]))
  117
+            except ImportError:
  118
+                pass # No management module - ignore this app
106 119
 
107 120
         if project_directory:
108 121
             # Remove the "startproject" command from self.commands, because
@@ -203,8 +216,6 @@ class ManagementUtility(object):
203 216
     def __init__(self, argv=None):
204 217
         self.argv = argv or sys.argv[:]
205 218
         self.prog_name = os.path.basename(self.argv[0])
206  
-        self.project_directory = None
207  
-        self.user_commands = False
208 219
 
209 220
     def main_help_text(self):
210 221
         """
@@ -212,7 +223,7 @@ def main_help_text(self):
212 223
         """
213 224
         usage = ['',"Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,'']
214 225
         usage.append('Available subcommands:')
215  
-        commands = get_commands(self.user_commands, self.project_directory).keys()
  226
+        commands = get_commands().keys()
216 227
         commands.sort()
217 228
         for cmd in commands:
218 229
             usage.append('  %s' % cmd)
@@ -225,7 +236,7 @@ def fetch_command(self, subcommand):
225 236
         "django-admin.py" or "manage.py") if it can't be found.
226 237
         """
227 238
         try:
228  
-            app_name = get_commands(self.user_commands, self.project_directory)[subcommand]
  239
+            app_name = get_commands()[subcommand]
229 240
             if isinstance(app_name, BaseCommand):
230 241
                 # If the command is already loaded, use it directly.
231 242
                 klass = app_name
@@ -278,20 +289,6 @@ def execute(self):
278 289
         else:
279 290
             self.fetch_command(subcommand).run_from_argv(self.argv)
280 291
 
281  
-class ProjectManagementUtility(ManagementUtility):
282  
-    """
283  
-    A ManagementUtility that is specific to a particular Django project.
284  
-    As such, its commands are slightly different than those of its parent
285  
-    class.
286  
-
287  
-    In practice, this class represents manage.py, whereas ManagementUtility
288  
-    represents django-admin.py.
289  
-    """
290  
-    def __init__(self, argv, project_directory):
291  
-        super(ProjectManagementUtility, self).__init__(argv)
292  
-        self.project_directory = project_directory
293  
-        self.user_commands = True
294  
-
295 292
 def setup_environ(settings_mod):
296 293
     """
297 294
     Configures the runtime environment. This can also be used by external
@@ -313,7 +310,6 @@ def setup_environ(settings_mod):
313 310
 
314 311
     # Set DJANGO_SETTINGS_MODULE appropriately.
315 312
     os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
316  
-    return project_directory
317 313
 
318 314
 def execute_from_command_line(argv=None):
319 315
     """
@@ -327,6 +323,6 @@ def execute_manager(settings_mod, argv=None):
327 323
     Like execute_from_command_line(), but for use by manage.py, a
328 324
     project-specific django-admin.py utility.
329 325
     """
330  
-    project_directory = setup_environ(settings_mod)
331  
-    utility = ProjectManagementUtility(argv, project_directory)
  326
+    setup_environ(settings_mod)
  327
+    utility = ManagementUtility(argv)
332 328
     utility.execute()
11  django/core/management/base.py
@@ -82,9 +82,14 @@ def execute(self, *args, **options):
82 82
         # But only do this if we can assume we have a working settings file,
83 83
         # because django.utils.translation requires settings.
84 84
         if self.can_import_settings:
85  
-            from django.utils import translation
86  
-            translation.activate('en-us')
87  
-
  85
+            try:
  86
+                from django.utils import translation
  87
+                translation.activate('en-us')
  88
+            except ImportError, e:
  89
+                # If settings should be available, but aren't, 
  90
+                # raise the error and quit.
  91
+                sys.stderr.write(self.style.ERROR(str('Error: %s\n' % e)))
  92
+                sys.exit(1)
88 93
         try:
89 94
             if self.requires_model_validation:
90 95
                 self.validate()
70  tests/regressiontests/admin_scripts/tests.py
@@ -223,25 +223,25 @@ def test_builtin_with_bad_environment(self):
223 223
         self.assertOutput(err, "Could not import settings 'bad_settings'")
224 224
 
225 225
     def test_custom_command(self):
226  
-        "default: django-admin can't execute user commands"
  226
+        "default: django-admin can't execute user commands if it isn't provided settings"
227 227
         args = ['noargs_command']
228 228
         out, err = self.run_django_admin(args)
229 229
         self.assertNoOutput(out)
230 230
         self.assertOutput(err, "Unknown command: 'noargs_command'")
231 231
 
232 232
     def test_custom_command_with_settings(self):
233  
-        "default: django-admin can't execute user commands, even if settings are provided as argument"
  233
+        "default: django-admin can execute user commands if settings are provided as argument"
234 234
         args = ['noargs_command', '--settings=settings']
235 235
         out, err = self.run_django_admin(args)
236  
-        self.assertNoOutput(out)
237  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  236
+        self.assertNoOutput(err)
  237
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
238 238
 
239 239
     def test_custom_command_with_environment(self):
240  
-        "default: django-admin can't execute user commands, even if settings are provided in environment"
  240
+        "default: django-admin can execute user commands if settings are provided in environment"
241 241
         args = ['noargs_command']
242 242
         out, err = self.run_django_admin(args,'settings')
243  
-        self.assertNoOutput(out)
244  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  243
+        self.assertNoOutput(err)
  244
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
245 245
 
246 246
 class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
247 247
     """A series of tests for django-admin.py when using a settings.py file that
@@ -261,18 +261,18 @@ def test_builtin_command(self):
261 261
         self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
262 262
 
263 263
     def test_builtin_with_settings(self):
264  
-        "fulldefault: django-admin builtin commands fail if user app isn't on path"
  264
+        "fulldefault: django-admin builtin commands succeed if a settings file is provided"
265 265
         args = ['sqlall','--settings=settings', 'admin_scripts']
266 266
         out, err = self.run_django_admin(args)
267  
-        self.assertNoOutput(out)
268  
-        self.assertOutput(err, 'ImportError: No module named regressiontests')
  267
+        self.assertNoOutput(err)
  268
+        self.assertOutput(out, 'CREATE TABLE')
269 269
 
270 270
     def test_builtin_with_environment(self):
271  
-        "fulldefault: django-admin builtin commands fail if user app isn't on path"
  271
+        "fulldefault: django-admin builtin commands succeed if the environment contains settings"
272 272
         args = ['sqlall','admin_scripts']
273 273
         out, err = self.run_django_admin(args,'settings')
274  
-        self.assertNoOutput(out)
275  
-        self.assertOutput(err, 'ImportError: No module named regressiontests')
  274
+        self.assertNoOutput(err)
  275
+        self.assertOutput(out, 'CREATE TABLE')
276 276
 
277 277
     def test_builtin_with_bad_settings(self):
278 278
         "fulldefault: django-admin builtin commands fail if settings file (from argument) doesn't exist"
@@ -289,25 +289,25 @@ def test_builtin_with_bad_environment(self):
289 289
         self.assertOutput(err, "Could not import settings 'bad_settings'")
290 290
 
291 291
     def test_custom_command(self):
292  
-        "fulldefault: django-admin can't execute user commands"
  292
+        "fulldefault: django-admin can't execute user commands unless settings are provided"
293 293
         args = ['noargs_command']
294 294
         out, err = self.run_django_admin(args)
295 295
         self.assertNoOutput(out)
296 296
         self.assertOutput(err, "Unknown command: 'noargs_command'")
297 297
 
298 298
     def test_custom_command_with_settings(self):
299  
-        "fulldefault: django-admin can't execute user commands, even if settings are provided as argument"
  299
+        "fulldefault: django-admin can execute user commands if settings are provided as argument"
300 300
         args = ['noargs_command', '--settings=settings']
301 301
         out, err = self.run_django_admin(args)
302  
-        self.assertNoOutput(out)
303  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  302
+        self.assertNoOutput(err)
  303
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
304 304
 
305 305
     def test_custom_command_with_environment(self):
306  
-        "fulldefault: django-admin can't execute user commands, even if settings are provided in environment"
  306
+        "fulldefault: django-admin can execute user commands if settings are provided in environment"
307 307
         args = ['noargs_command']
308 308
         out, err = self.run_django_admin(args,'settings')
309  
-        self.assertNoOutput(out)
310  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  309
+        self.assertNoOutput(err)
  310
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
311 311
 
312 312
 class DjangoAdminMinimalSettings(AdminScriptTestCase):
313 313
     """A series of tests for django-admin.py when using a settings.py file that
@@ -355,7 +355,7 @@ def test_builtin_with_bad_environment(self):
355 355
         self.assertOutput(err, "Could not import settings 'bad_settings'")
356 356
 
357 357
     def test_custom_command(self):
358  
-        "minimal: django-admin can't execute user commands"
  358
+        "minimal: django-admin can't execute user commands unless settings are provided"
359 359
         args = ['noargs_command']
360 360
         out, err = self.run_django_admin(args)
361 361
         self.assertNoOutput(out)
@@ -420,26 +420,26 @@ def test_builtin_with_bad_environment(self):
420 420
         self.assertNoOutput(out)
421 421
         self.assertOutput(err, "Could not import settings 'bad_settings'")
422 422
 
423  
-    def test_custom_command(self):
424  
-        "alternate: django-admin can't execute user commands"
  423
+    def test_custom_command(self): 
  424
+        "alternate: django-admin can't execute user commands unless settings are provided"
425 425
         args = ['noargs_command']
426 426
         out, err = self.run_django_admin(args)
427 427
         self.assertNoOutput(out)
428 428
         self.assertOutput(err, "Unknown command: 'noargs_command'")
429 429
 
430 430
     def test_custom_command_with_settings(self):
431  
-        "alternate: django-admin can't execute user commands, even if settings are provided as argument"
  431
+        "alternate: django-admin can execute user commands if settings are provided as argument"
432 432
         args = ['noargs_command', '--settings=alternate_settings']
433 433
         out, err = self.run_django_admin(args)
434  
-        self.assertNoOutput(out)
435  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  434
+        self.assertNoOutput(err)
  435
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
436 436
 
437 437
     def test_custom_command_with_environment(self):
438  
-        "alternate: django-admin can't execute user commands, even if settings are provided in environment"
  438
+        "alternate: django-admin can execute user commands if settings are provided in environment"
439 439
         args = ['noargs_command']
440 440
         out, err = self.run_django_admin(args,'alternate_settings')
441  
-        self.assertNoOutput(out)
442  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  441
+        self.assertNoOutput(err)
  442
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
443 443
 
444 444
 
445 445
 class DjangoAdminMultipleSettings(AdminScriptTestCase):
@@ -490,8 +490,8 @@ def test_builtin_with_bad_environment(self):
490 490
         self.assertNoOutput(out)
491 491
         self.assertOutput(err, "Could not import settings 'bad_settings'")
492 492
 
493  
-    def test_custom_command(self):
494  
-        "alternate: django-admin can't execute user commands"
  493
+    def test_custom_command(self): 
  494
+        "alternate: django-admin can't execute user commands unless settings are provided"
495 495
         args = ['noargs_command']
496 496
         out, err = self.run_django_admin(args)
497 497
         self.assertNoOutput(out)
@@ -501,15 +501,15 @@ def test_custom_command_with_settings(self):
501 501
         "alternate: django-admin can't execute user commands, even if settings are provided as argument"
502 502
         args = ['noargs_command', '--settings=alternate_settings']
503 503
         out, err = self.run_django_admin(args)
504  
-        self.assertNoOutput(out)
505  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  504
+        self.assertNoOutput(err)
  505
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
506 506
 
507 507
     def test_custom_command_with_environment(self):
508 508
         "alternate: django-admin can't execute user commands, even if settings are provided in environment"
509 509
         args = ['noargs_command']
510 510
         out, err = self.run_django_admin(args,'alternate_settings')
511  
-        self.assertNoOutput(out)
512  
-        self.assertOutput(err, "Unknown command: 'noargs_command'")
  511
+        self.assertNoOutput(err)
  512
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
513 513
 
514 514
 ##########################################################################
515 515
 # MANAGE.PY TESTS

0 notes on commit ec7d8b7

Please sign in to comment.
Something went wrong with that request. Please try again.