Moved all logic from django-admin.py into django.core.management, into a new execute_from_command_line() function, so it can be called from other scripts. Also improved createproject to disallow 'django' and 'test' as project names.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@1553 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
85c369001b
commit
6d210ef403
|
@ -1,153 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from django.core import management
|
from django.core import management
|
||||||
from optparse import OptionParser
|
|
||||||
import os, sys, textwrap
|
|
||||||
|
|
||||||
ACTION_MAPPING = {
|
|
||||||
'adminindex': management.get_admin_index,
|
|
||||||
'createsuperuser': management.createsuperuser,
|
|
||||||
'createcachetable' : management.createcachetable,
|
|
||||||
# 'dbcheck': management.database_check,
|
|
||||||
'init': management.init,
|
|
||||||
'inspectdb': management.inspectdb,
|
|
||||||
'install': management.install,
|
|
||||||
'installperms': management.installperms,
|
|
||||||
'runserver': management.runserver,
|
|
||||||
'sql': management.get_sql_create,
|
|
||||||
'sqlall': management.get_sql_all,
|
|
||||||
'sqlclear': management.get_sql_delete,
|
|
||||||
'sqlindexes': management.get_sql_indexes,
|
|
||||||
'sqlinitialdata': management.get_sql_initial_data,
|
|
||||||
'sqlreset': management.get_sql_reset,
|
|
||||||
'sqlsequencereset': management.get_sql_sequence_reset,
|
|
||||||
'startapp': management.startapp,
|
|
||||||
'startproject': management.startproject,
|
|
||||||
'validate': management.validate,
|
|
||||||
}
|
|
||||||
|
|
||||||
NO_SQL_TRANSACTION = ('adminindex', 'createcachetable', 'dbcheck', 'install', 'installperms', 'sqlindexes')
|
|
||||||
|
|
||||||
def get_usage():
|
|
||||||
"""
|
|
||||||
Returns a usage string. Doesn't do the options stuff, because optparse
|
|
||||||
takes care of that.
|
|
||||||
"""
|
|
||||||
usage = ["usage: %prog action [options]\nactions:"]
|
|
||||||
available_actions = ACTION_MAPPING.keys()
|
|
||||||
available_actions.sort()
|
|
||||||
for a in available_actions:
|
|
||||||
func = ACTION_MAPPING[a]
|
|
||||||
usage.append(" %s %s" % (a, func.args))
|
|
||||||
usage.extend(textwrap.wrap(getattr(func, 'help_doc', func.__doc__), initial_indent=' ', subsequent_indent=' '))
|
|
||||||
usage.append("")
|
|
||||||
return '\n'.join(usage[:-1]) # Cut off last list element, an empty space.
|
|
||||||
|
|
||||||
class DjangoOptionParser(OptionParser):
|
|
||||||
def print_usage_and_exit(self):
|
|
||||||
self.print_help(sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def print_error(msg, cmd):
|
|
||||||
sys.stderr.write('Error: %s\nRun "%s --help" for help.\n' % (msg, cmd))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Parse the command-line arguments. optparse handles the dirty work.
|
|
||||||
parser = DjangoOptionParser(get_usage())
|
|
||||||
parser.add_option('--settings',
|
|
||||||
help='Python path to settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
|
|
||||||
parser.add_option('--pythonpath',
|
|
||||||
help='Lets you manually add a directory the Python path, e.g. "/home/djangoprojects/myproject".')
|
|
||||||
options, args = parser.parse_args()
|
|
||||||
|
|
||||||
# Take care of options.
|
|
||||||
if options.settings:
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
|
|
||||||
if options.pythonpath:
|
|
||||||
sys.path.insert(0, options.pythonpath)
|
|
||||||
|
|
||||||
# Run the appropriate action. Unfortunately, optparse can't handle
|
|
||||||
# positional arguments, so this has to parse/validate them.
|
|
||||||
try:
|
|
||||||
action = args[0]
|
|
||||||
except IndexError:
|
|
||||||
parser.print_usage_and_exit()
|
|
||||||
if not ACTION_MAPPING.has_key(action):
|
|
||||||
print_error("Your action, %r, was invalid." % action, sys.argv[0])
|
|
||||||
|
|
||||||
# switch to english, because django-admin creates database content
|
|
||||||
# like permissions, and those shouldn't contain any translations.
|
|
||||||
# But only do this if we should have a working settings file.
|
|
||||||
if action not in ('startproject', 'startapp'):
|
|
||||||
from django.utils import translation
|
|
||||||
translation.activate('en-us')
|
|
||||||
|
|
||||||
if action == 'createsuperuser':
|
|
||||||
try:
|
|
||||||
username, email, password = args[1], args[2], args[3]
|
|
||||||
except IndexError:
|
|
||||||
if len(args) == 1: # We got no arguments, just the action.
|
|
||||||
ACTION_MAPPING[action]()
|
|
||||||
else:
|
|
||||||
sys.stderr.write("Error: %r requires arguments of 'username email password' or no argument at all.\n")
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
ACTION_MAPPING[action](username, email, password)
|
|
||||||
elif action in ('init', 'validate'):
|
|
||||||
ACTION_MAPPING[action]()
|
|
||||||
elif action == 'inspectdb':
|
|
||||||
try:
|
|
||||||
param = args[1]
|
|
||||||
except IndexError:
|
|
||||||
parser.print_usage_and_exit()
|
|
||||||
try:
|
|
||||||
for line in ACTION_MAPPING[action](param):
|
|
||||||
print line
|
|
||||||
except NotImplementedError:
|
|
||||||
sys.stderr.write("Error: %r isn't supported for the currently selected database backend.\n" % action)
|
|
||||||
sys.exit(1)
|
|
||||||
elif action == 'createcachetable':
|
|
||||||
try:
|
|
||||||
ACTION_MAPPING[action](args[1])
|
|
||||||
except IndexError:
|
|
||||||
parser.print_usage_and_exit()
|
|
||||||
elif action in ('startapp', 'startproject'):
|
|
||||||
try:
|
|
||||||
name = args[1]
|
|
||||||
except IndexError:
|
|
||||||
parser.print_usage_and_exit()
|
|
||||||
ACTION_MAPPING[action](name, os.getcwd())
|
|
||||||
elif action == 'runserver':
|
|
||||||
if len(args) < 2:
|
|
||||||
addr = ''
|
|
||||||
port = '8000'
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
addr, port = args[1].split(':')
|
|
||||||
except ValueError:
|
|
||||||
addr, port = '', args[1]
|
|
||||||
ACTION_MAPPING[action](addr, port)
|
|
||||||
else:
|
|
||||||
from django.core import meta
|
|
||||||
if action == 'dbcheck':
|
|
||||||
mod_list = meta.get_all_installed_modules()
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
mod_list = [meta.get_app(app_label) for app_label in args[1:]]
|
|
||||||
except ImportError, e:
|
|
||||||
sys.stderr.write("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e)
|
|
||||||
sys.exit(1)
|
|
||||||
if not mod_list:
|
|
||||||
parser.print_usage_and_exit()
|
|
||||||
if action not in NO_SQL_TRANSACTION:
|
|
||||||
print "BEGIN;"
|
|
||||||
for mod in mod_list:
|
|
||||||
output = ACTION_MAPPING[action](mod)
|
|
||||||
if output:
|
|
||||||
print '\n'.join(output)
|
|
||||||
if action not in NO_SQL_TRANSACTION:
|
|
||||||
print "COMMIT;"
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
management.execute_from_command_line()
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
# development-server initialization.
|
# development-server initialization.
|
||||||
|
|
||||||
import django
|
import django
|
||||||
import os, re, sys
|
import os, re, sys, textwrap
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
MODULE_TEMPLATE = ''' {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%}
|
MODULE_TEMPLATE = ''' {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%}
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -18,6 +19,8 @@ APP_ARGS = '[modelmodule ...]'
|
||||||
# which has been installed.
|
# which has been installed.
|
||||||
PROJECT_TEMPLATE_DIR = os.path.join(django.__path__[0], 'conf', '%s_template')
|
PROJECT_TEMPLATE_DIR = os.path.join(django.__path__[0], 'conf', '%s_template')
|
||||||
|
|
||||||
|
INVALID_PROJECT_NAMES = ('django', 'test')
|
||||||
|
|
||||||
def _get_packages_insert(app_label):
|
def _get_packages_insert(app_label):
|
||||||
from django.core.db import db
|
from django.core.db import db
|
||||||
return "INSERT INTO %s (%s, %s) VALUES ('%s', '%s');" % \
|
return "INSERT INTO %s (%s, %s) VALUES ('%s', '%s');" % \
|
||||||
|
@ -471,6 +474,9 @@ def _start_helper(app_or_project, name, directory, other_name=''):
|
||||||
def startproject(project_name, directory):
|
def startproject(project_name, directory):
|
||||||
"Creates a Django project for the given project_name in the given directory."
|
"Creates a Django project for the given project_name in the given directory."
|
||||||
from random import choice
|
from random import choice
|
||||||
|
if project_name in INVALID_PROJECT_NAMES:
|
||||||
|
sys.stderr.write("Error: %r isn't a valid project name. Please try another.\n" % project_name)
|
||||||
|
sys.exit(1)
|
||||||
_start_helper('project', project_name, directory)
|
_start_helper('project', project_name, directory)
|
||||||
# Create a random SECRET_KEY hash, and put it in the main settings.
|
# Create a random SECRET_KEY hash, and put it in the main settings.
|
||||||
main_settings_file = os.path.join(directory, project_name, 'settings.py')
|
main_settings_file = os.path.join(directory, project_name, 'settings.py')
|
||||||
|
@ -807,3 +813,150 @@ def createcachetable(tablename):
|
||||||
curs.execute(statement)
|
curs.execute(statement)
|
||||||
db.db.commit()
|
db.db.commit()
|
||||||
createcachetable.args = "[tablename]"
|
createcachetable.args = "[tablename]"
|
||||||
|
|
||||||
|
# Utilities for command-line script
|
||||||
|
|
||||||
|
ACTION_MAPPING = {
|
||||||
|
'adminindex': get_admin_index,
|
||||||
|
'createsuperuser': createsuperuser,
|
||||||
|
'createcachetable' : createcachetable,
|
||||||
|
# 'dbcheck': database_check,
|
||||||
|
'init': init,
|
||||||
|
'inspectdb': inspectdb,
|
||||||
|
'install': install,
|
||||||
|
'installperms': installperms,
|
||||||
|
'runserver': runserver,
|
||||||
|
'sql': get_sql_create,
|
||||||
|
'sqlall': get_sql_all,
|
||||||
|
'sqlclear': get_sql_delete,
|
||||||
|
'sqlindexes': get_sql_indexes,
|
||||||
|
'sqlinitialdata': get_sql_initial_data,
|
||||||
|
'sqlreset': get_sql_reset,
|
||||||
|
'sqlsequencereset': get_sql_sequence_reset,
|
||||||
|
'startapp': startapp,
|
||||||
|
'startproject': startproject,
|
||||||
|
'validate': validate,
|
||||||
|
}
|
||||||
|
|
||||||
|
NO_SQL_TRANSACTION = ('adminindex', 'createcachetable', 'dbcheck', 'install', 'installperms', 'sqlindexes')
|
||||||
|
|
||||||
|
class DjangoOptionParser(OptionParser):
|
||||||
|
def print_usage_and_exit(self):
|
||||||
|
self.print_help(sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def get_usage():
|
||||||
|
"""
|
||||||
|
Returns a usage string. Doesn't do the options stuff, because optparse
|
||||||
|
takes care of that.
|
||||||
|
"""
|
||||||
|
usage = ["usage: %prog action [options]\nactions:"]
|
||||||
|
available_actions = ACTION_MAPPING.keys()
|
||||||
|
available_actions.sort()
|
||||||
|
for a in available_actions:
|
||||||
|
func = ACTION_MAPPING[a]
|
||||||
|
usage.append(" %s %s" % (a, func.args))
|
||||||
|
usage.extend(textwrap.wrap(getattr(func, 'help_doc', func.__doc__), initial_indent=' ', subsequent_indent=' '))
|
||||||
|
usage.append("")
|
||||||
|
return '\n'.join(usage[:-1]) # Cut off last list element, an empty space.
|
||||||
|
|
||||||
|
def print_error(msg, cmd):
|
||||||
|
sys.stderr.write('Error: %s\nRun "%s --help" for help.\n' % (msg, cmd))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def execute_from_command_line():
|
||||||
|
# Parse the command-line arguments. optparse handles the dirty work.
|
||||||
|
parser = DjangoOptionParser(get_usage())
|
||||||
|
parser.add_option('--settings',
|
||||||
|
help='Python path to settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
|
||||||
|
parser.add_option('--pythonpath',
|
||||||
|
help='Lets you manually add a directory the Python path, e.g. "/home/djangoprojects/myproject".')
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
# Take care of options.
|
||||||
|
if options.settings:
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
|
||||||
|
if options.pythonpath:
|
||||||
|
sys.path.insert(0, options.pythonpath)
|
||||||
|
|
||||||
|
# Run the appropriate action. Unfortunately, optparse can't handle
|
||||||
|
# positional arguments, so this has to parse/validate them.
|
||||||
|
try:
|
||||||
|
action = args[0]
|
||||||
|
except IndexError:
|
||||||
|
parser.print_usage_and_exit()
|
||||||
|
if not ACTION_MAPPING.has_key(action):
|
||||||
|
print_error("Your action, %r, was invalid." % action, sys.argv[0])
|
||||||
|
|
||||||
|
# switch to english, because django-admin creates database content
|
||||||
|
# like permissions, and those shouldn't contain any translations.
|
||||||
|
# But only do this if we should have a working settings file.
|
||||||
|
if action not in ('startproject', 'startapp'):
|
||||||
|
from django.utils import translation
|
||||||
|
translation.activate('en-us')
|
||||||
|
|
||||||
|
if action == 'createsuperuser':
|
||||||
|
try:
|
||||||
|
username, email, password = args[1], args[2], args[3]
|
||||||
|
except IndexError:
|
||||||
|
if len(args) == 1: # We got no arguments, just the action.
|
||||||
|
ACTION_MAPPING[action]()
|
||||||
|
else:
|
||||||
|
sys.stderr.write("Error: %r requires arguments of 'username email password' or no argument at all.\n")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
ACTION_MAPPING[action](username, email, password)
|
||||||
|
elif action in ('init', 'validate'):
|
||||||
|
ACTION_MAPPING[action]()
|
||||||
|
elif action == 'inspectdb':
|
||||||
|
try:
|
||||||
|
param = args[1]
|
||||||
|
except IndexError:
|
||||||
|
parser.print_usage_and_exit()
|
||||||
|
try:
|
||||||
|
for line in ACTION_MAPPING[action](param):
|
||||||
|
print line
|
||||||
|
except NotImplementedError:
|
||||||
|
sys.stderr.write("Error: %r isn't supported for the currently selected database backend.\n" % action)
|
||||||
|
sys.exit(1)
|
||||||
|
elif action == 'createcachetable':
|
||||||
|
try:
|
||||||
|
ACTION_MAPPING[action](args[1])
|
||||||
|
except IndexError:
|
||||||
|
parser.print_usage_and_exit()
|
||||||
|
elif action in ('startapp', 'startproject'):
|
||||||
|
try:
|
||||||
|
name = args[1]
|
||||||
|
except IndexError:
|
||||||
|
parser.print_usage_and_exit()
|
||||||
|
ACTION_MAPPING[action](name, os.getcwd())
|
||||||
|
elif action == 'runserver':
|
||||||
|
if len(args) < 2:
|
||||||
|
addr = ''
|
||||||
|
port = '8000'
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
addr, port = args[1].split(':')
|
||||||
|
except ValueError:
|
||||||
|
addr, port = '', args[1]
|
||||||
|
ACTION_MAPPING[action](addr, port)
|
||||||
|
else:
|
||||||
|
from django.core import meta
|
||||||
|
if action == 'dbcheck':
|
||||||
|
mod_list = meta.get_all_installed_modules()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
mod_list = [meta.get_app(app_label) for app_label in args[1:]]
|
||||||
|
except ImportError, e:
|
||||||
|
sys.stderr.write("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e)
|
||||||
|
sys.exit(1)
|
||||||
|
if not mod_list:
|
||||||
|
parser.print_usage_and_exit()
|
||||||
|
if action not in NO_SQL_TRANSACTION:
|
||||||
|
print "BEGIN;"
|
||||||
|
for mod in mod_list:
|
||||||
|
output = ACTION_MAPPING[action](mod)
|
||||||
|
if output:
|
||||||
|
print '\n'.join(output)
|
||||||
|
if action not in NO_SQL_TRANSACTION:
|
||||||
|
print "COMMIT;"
|
||||||
|
|
Loading…
Reference in New Issue