Fixed #5943 -- Modified django-admin to behave like manage.py if settings 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
This commit is contained in:
Russell Keith-Magee 2008-08-10 08:42:49 +00:00
parent 7610983bb2
commit ec7d8b7c61
3 changed files with 70 additions and 69 deletions

View File

@ -66,7 +66,7 @@ def load_command_class(app_name, name):
return getattr(__import__('%s.management.commands.%s' % (app_name, name),
{}, {}, ['Command']), 'Command')()
def get_commands(load_user_commands=True, project_directory=None):
def get_commands():
"""
Returns a dictionary mapping command names to their callback applications.
@ -77,7 +77,7 @@ def get_commands(load_user_commands=True, project_directory=None):
Core commands are always included. If a settings module has been
specified, user-defined commands will also be included, the
startproject command will be disabled, and the startapp command
will be modified to use the directory in which that module appears.
will be modified to use the directory in which the settings module appears.
The dictionary is in the format {command_name: app_name}. Key-value
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):
if _commands is None:
_commands = dict([(name, 'django.core') for name in find_commands(__path__[0])])
if load_user_commands:
# Get commands from all installed apps.
# Find the installed apps
try:
from django.conf import settings
for app_name in settings.INSTALLED_APPS:
try:
path = find_management_module(app_name)
_commands.update(dict([(name, app_name) for name in find_commands(path)]))
except ImportError:
pass # No management module -- ignore this app.
apps = settings.INSTALLED_APPS
except (AttributeError, EnvironmentError, ImportError):
apps = []
# Find the project directory
try:
from django.conf import settings
project_directory = setup_environ(__import__(settings.SETTINGS_MODULE))
except (AttributeError, EnvironmentError, ImportError):
project_directory = None
# Find and load the management module for each installed app.
for app_name in apps:
try:
path = find_management_module(app_name)
_commands.update(dict([(name, app_name)
for name in find_commands(path)]))
except ImportError:
pass # No management module - ignore this app
if project_directory:
# Remove the "startproject" command from self.commands, because
@ -203,8 +216,6 @@ class ManagementUtility(object):
def __init__(self, argv=None):
self.argv = argv or sys.argv[:]
self.prog_name = os.path.basename(self.argv[0])
self.project_directory = None
self.user_commands = False
def main_help_text(self):
"""
@ -212,7 +223,7 @@ class ManagementUtility(object):
"""
usage = ['',"Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,'']
usage.append('Available subcommands:')
commands = get_commands(self.user_commands, self.project_directory).keys()
commands = get_commands().keys()
commands.sort()
for cmd in commands:
usage.append(' %s' % cmd)
@ -225,7 +236,7 @@ class ManagementUtility(object):
"django-admin.py" or "manage.py") if it can't be found.
"""
try:
app_name = get_commands(self.user_commands, self.project_directory)[subcommand]
app_name = get_commands()[subcommand]
if isinstance(app_name, BaseCommand):
# If the command is already loaded, use it directly.
klass = app_name
@ -278,20 +289,6 @@ class ManagementUtility(object):
else:
self.fetch_command(subcommand).run_from_argv(self.argv)
class ProjectManagementUtility(ManagementUtility):
"""
A ManagementUtility that is specific to a particular Django project.
As such, its commands are slightly different than those of its parent
class.
In practice, this class represents manage.py, whereas ManagementUtility
represents django-admin.py.
"""
def __init__(self, argv, project_directory):
super(ProjectManagementUtility, self).__init__(argv)
self.project_directory = project_directory
self.user_commands = True
def setup_environ(settings_mod):
"""
Configures the runtime environment. This can also be used by external
@ -313,7 +310,6 @@ def setup_environ(settings_mod):
# Set DJANGO_SETTINGS_MODULE appropriately.
os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
return project_directory
def execute_from_command_line(argv=None):
"""
@ -327,6 +323,6 @@ def execute_manager(settings_mod, argv=None):
Like execute_from_command_line(), but for use by manage.py, a
project-specific django-admin.py utility.
"""
project_directory = setup_environ(settings_mod)
utility = ProjectManagementUtility(argv, project_directory)
setup_environ(settings_mod)
utility = ManagementUtility(argv)
utility.execute()

View File

@ -82,9 +82,14 @@ class BaseCommand(object):
# But only do this if we can assume we have a working settings file,
# because django.utils.translation requires settings.
if self.can_import_settings:
from django.utils import translation
translation.activate('en-us')
try:
from django.utils import translation
translation.activate('en-us')
except ImportError, e:
# If settings should be available, but aren't,
# raise the error and quit.
sys.stderr.write(self.style.ERROR(str('Error: %s\n' % e)))
sys.exit(1)
try:
if self.requires_model_validation:
self.validate()

View File

@ -223,25 +223,25 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self):
"default: django-admin can't execute user commands"
"default: django-admin can't execute user commands if it isn't provided settings"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
def test_custom_command_with_settings(self):
"default: django-admin can't execute user commands, even if settings are provided as argument"
"default: django-admin can execute user commands if settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
def test_custom_command_with_environment(self):
"default: django-admin can't execute user commands, even if settings are provided in environment"
"default: django-admin can execute user commands if settings are provided in environment"
args = ['noargs_command']
out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
"""A series of tests for django-admin.py when using a settings.py file that
@ -261,18 +261,18 @@ class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
def test_builtin_with_settings(self):
"fulldefault: django-admin builtin commands fail if user app isn't on path"
"fulldefault: django-admin builtin commands succeed if a settings file is provided"
args = ['sqlall','--settings=settings', 'admin_scripts']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, 'ImportError: No module named regressiontests')
self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE')
def test_builtin_with_environment(self):
"fulldefault: django-admin builtin commands fail if user app isn't on path"
"fulldefault: django-admin builtin commands succeed if the environment contains settings"
args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out)
self.assertOutput(err, 'ImportError: No module named regressiontests')
self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE')
def test_builtin_with_bad_settings(self):
"fulldefault: django-admin builtin commands fail if settings file (from argument) doesn't exist"
@ -289,25 +289,25 @@ class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self):
"fulldefault: django-admin can't execute user commands"
"fulldefault: django-admin can't execute user commands unless settings are provided"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
def test_custom_command_with_settings(self):
"fulldefault: django-admin can't execute user commands, even if settings are provided as argument"
"fulldefault: django-admin can execute user commands if settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
def test_custom_command_with_environment(self):
"fulldefault: django-admin can't execute user commands, even if settings are provided in environment"
"fulldefault: django-admin can execute user commands if settings are provided in environment"
args = ['noargs_command']
out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
class DjangoAdminMinimalSettings(AdminScriptTestCase):
"""A series of tests for django-admin.py when using a settings.py file that
@ -355,7 +355,7 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self):
"minimal: django-admin can't execute user commands"
"minimal: django-admin can't execute user commands unless settings are provided"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
@ -420,26 +420,26 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self):
"alternate: django-admin can't execute user commands"
def test_custom_command(self):
"alternate: django-admin can't execute user commands unless settings are provided"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
def test_custom_command_with_settings(self):
"alternate: django-admin can't execute user commands, even if settings are provided as argument"
"alternate: django-admin can execute user commands if settings are provided as argument"
args = ['noargs_command', '--settings=alternate_settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
def test_custom_command_with_environment(self):
"alternate: django-admin can't execute user commands, even if settings are provided in environment"
"alternate: django-admin can execute user commands if settings are provided in environment"
args = ['noargs_command']
out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
class DjangoAdminMultipleSettings(AdminScriptTestCase):
@ -490,8 +490,8 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self):
"alternate: django-admin can't execute user commands"
def test_custom_command(self):
"alternate: django-admin can't execute user commands unless settings are provided"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
@ -501,15 +501,15 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
"alternate: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=alternate_settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
def test_custom_command_with_environment(self):
"alternate: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command']
out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
##########################################################################
# MANAGE.PY TESTS