diff options
author | Arthur Koziel <arthur@arthurkoziel.com> | 2010-09-13 00:04:27 +0000 |
---|---|---|
committer | Arthur Koziel <arthur@arthurkoziel.com> | 2010-09-13 00:04:27 +0000 |
commit | dd49269c7db008b2567f50cb03c4d3d9b321daa1 (patch) | |
tree | 326dd25bb045ac016cda7966b43cbdfe1f67d699 /django/core/management | |
parent | c9b188c4ec939abbe48dae5a371276742e64b6b8 (diff) | |
download | django-soc2010/app-loading.tar.gz |
[soc2010/app-loading] merged trunkarchive/soc2010/app-loadingsoc2010/app-loading
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/app-loading@13818 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core/management')
-rw-r--r-- | django/core/management/__init__.py | 10 | ||||
-rw-r--r-- | django/core/management/base.py | 24 | ||||
-rw-r--r-- | django/core/management/commands/dumpdata.py | 43 | ||||
-rw-r--r-- | django/core/management/commands/flush.py | 10 | ||||
-rw-r--r-- | django/core/management/commands/loaddata.py | 71 | ||||
-rw-r--r-- | django/core/management/commands/syncdb.py | 14 | ||||
-rw-r--r-- | django/core/management/commands/testserver.py | 5 |
7 files changed, 116 insertions, 61 deletions
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index a61b648674..dabde96377 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -250,15 +250,15 @@ class ManagementUtility(object): """ try: app_name = get_commands()[subcommand] - if isinstance(app_name, BaseCommand): - # If the command is already loaded, use it directly. - klass = app_name - else: - klass = load_command_class(app_name, subcommand) except KeyError: sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \ (subcommand, self.prog_name)) sys.exit(1) + if isinstance(app_name, BaseCommand): + # If the command is already loaded, use it directly. + klass = app_name + else: + klass = load_command_class(app_name, subcommand) return klass def autocomplete(self): diff --git a/django/core/management/base.py b/django/core/management/base.py index 4016faaa7a..dcd83ff300 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -118,7 +118,7 @@ class BaseCommand(object): # Metadata about this command. option_list = ( make_option('-v', '--verbosity', action='store', dest='verbosity', default='1', - type='choice', choices=['0', '1', '2'], + type='choice', choices=['0', '1', '2', '3'], help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), make_option('--settings', 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.'), @@ -213,20 +213,24 @@ class BaseCommand(object): sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) sys.exit(1) try: + self.stdout = options.get('stdout', sys.stdout) + self.stderr = options.get('stderr', sys.stderr) if self.requires_model_validation: self.validate() output = self.handle(*args, **options) if output: if self.output_transaction: - # This needs to be imported here, because it relies on settings. - from django.db import connection + # This needs to be imported here, because it relies on + # settings. + from django.db import connections, DEFAULT_DB_ALIAS + connection = connections[options.get('database', DEFAULT_DB_ALIAS)] if connection.ops.start_transaction_sql(): - print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) - print output + self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())) + self.stdout.write(output) if self.output_transaction: - print self.style.SQL_KEYWORD("COMMIT;") + self.stdout.write(self.style.SQL_KEYWORD("COMMIT;") + '\n') except CommandError, e: - sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) + self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) sys.exit(1) def validate(self, app=None, display_num_errors=False): @@ -248,7 +252,7 @@ class BaseCommand(object): error_text = s.read() raise CommandError("One or more models did not validate:\n%s" % error_text) if display_num_errors: - print "%s error%s found" % (num_errors, num_errors != 1 and 's' or '') + self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or '')) def handle(self, *args, **options): """ @@ -390,9 +394,9 @@ def copy_helper(style, app_or_project, name, directory, other_name=''): relative_dir = d[len(template_dir)+1:].replace('%s_name' % app_or_project, name) if relative_dir: os.mkdir(os.path.join(top_dir, relative_dir)) - for i, subdir in enumerate(subdirs): + for subdir in subdirs[:]: if subdir.startswith('.'): - del subdirs[i] + subdirs.remove(subdir) for f in files: if not f.endswith('.py'): # Ignore .pyc, .pyo, .py.class etc, as they cause various diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index aaaa5845a5..706bf601f9 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -16,11 +16,15 @@ class Command(BaseCommand): default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load ' 'fixtures into. Defaults to the "default" database.'), make_option('-e', '--exclude', dest='exclude',action='append', default=[], - help='App to exclude (use multiple --exclude to exclude multiple apps).'), + help='An appname or appname.ModelName to exclude (use multiple --exclude to exclude multiple apps/models).'), make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False, help='Use natural keys if they are available.'), + make_option('-a', '--all', action='store_true', dest='use_base_manager', default=False, + help="Use Django's base manager to dump all models stored in the database, including those that would otherwise be filtered or modified by a custom manager."), ) - help = 'Output the contents of the database as a fixture of the given format.' + help = ("Output the contents of the database as a fixture of the given " + "format (using each model's default manager unless --all is " + "specified).") args = '[appname appname.ModelName ...]' def handle(self, *app_labels, **options): @@ -30,11 +34,26 @@ class Command(BaseCommand): indent = options.get('indent',None) using = options.get('database', DEFAULT_DB_ALIAS) connection = connections[using] - exclude = options.get('exclude',[]) + excludes = options.get('exclude',[]) show_traceback = options.get('traceback', False) use_natural_keys = options.get('use_natural_keys', False) - - excluded_apps = set(get_app(app_label) for app_label in exclude) + use_base_manager = options.get('use_base_manager', False) + + excluded_apps = set() + excluded_models = set() + for exclude in excludes: + if '.' in exclude: + app_label, model_name = exclude.split('.', 1) + model_obj = get_model(app_label, model_name) + if not model_obj: + raise CommandError('Unknown model in excludes: %s' % exclude) + excluded_models.add(model_obj) + else: + try: + app_obj = get_app(exclude) + excluded_apps.add(app_obj) + except ImproperlyConfigured: + raise CommandError('Unknown app in excludes: %s' % exclude) if len(app_labels) == 0: app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps) @@ -47,7 +66,8 @@ class Command(BaseCommand): app = get_app(app_label) except ImproperlyConfigured: raise CommandError("Unknown application: %s" % app_label) - + if app in excluded_apps: + continue model = get_model(app_label, model_label) if model is None: raise CommandError("Unknown model: %s.%s" % (app_label, model_label)) @@ -64,6 +84,8 @@ class Command(BaseCommand): app = get_app(app_label) except ImproperlyConfigured: raise CommandError("Unknown application: %s" % app_label) + if app in excluded_apps: + continue app_list[app] = None # Check that the serialization format exists; this is a shortcut to @@ -79,8 +101,13 @@ class Command(BaseCommand): # Now collate the objects to be serialized. objects = [] for model in sort_dependencies(app_list.items()): + if model in excluded_models: + continue if not model._meta.proxy and router.allow_syncdb(using, model): - objects.extend(model._default_manager.using(using).all()) + if use_base_manager: + objects.extend(model._base_manager.using(using).all()) + else: + objects.extend(model._default_manager.using(using).all()) try: return serializers.serialize(format, objects, indent=indent, @@ -163,4 +190,4 @@ def sort_dependencies(app_list): ) model_dependencies = skipped - return model_list
\ No newline at end of file + return model_list diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index 6836fe35ca..093c6db7b9 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -1,7 +1,7 @@ from optparse import make_option from django.conf import settings -from django.db import connections, transaction, models, DEFAULT_DB_ALIAS +from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS from django.core.management import call_command from django.core.management.base import NoArgsCommand, CommandError from django.core.management.color import no_style @@ -66,7 +66,13 @@ The full error: %s""" % (connection.settings_dict['NAME'], e)) # Emit the post sync signal. This allows individual # applications to respond as if the database had been # sync'd from scratch. - emit_post_sync_signal(models.get_models(), verbosity, interactive, db) + all_models = [] + for app in models.get_apps(): + all_models.extend([ + m for m in models.get_models(app, include_auto_created=True) + if router.allow_syncdb(db, m) + ]) + emit_post_sync_signal(set(all_models), verbosity, interactive, db) # Reinstall the initial_data fixture. kwargs = options.copy() diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 6212d6151d..0b752b57e2 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -47,7 +47,8 @@ class Command(BaseCommand): # Keep a count of the installed objects and fixtures fixture_count = 0 - object_count = 0 + loaded_object_count = 0 + fixture_object_count = 0 models = set() humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' @@ -111,11 +112,11 @@ class Command(BaseCommand): formats = [] if formats: - if verbosity > 1: - print "Loading '%s' fixtures..." % fixture_name + if verbosity >= 2: + self.stdout.write("Loading '%s' fixtures...\n" % fixture_name) else: - sys.stderr.write( - self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." % + self.stderr.write( + self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format.\n" % (fixture_name, format))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) @@ -127,8 +128,8 @@ class Command(BaseCommand): fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + [''] for fixture_dir in fixture_dirs: - if verbosity > 1: - print "Checking %s for fixtures..." % humanize(fixture_dir) + if verbosity >= 2: + self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir)) label_found = False for combo in product([using, None], formats, compression_formats): @@ -140,34 +141,37 @@ class Command(BaseCommand): if p ) - if verbosity > 1: - print "Trying %s for %s fixture '%s'..." % \ - (humanize(fixture_dir), file_name, fixture_name) + if verbosity >= 3: + self.stdout.write("Trying %s for %s fixture '%s'...\n" % \ + (humanize(fixture_dir), file_name, fixture_name)) full_path = os.path.join(fixture_dir, file_name) open_method = compression_types[compression_format] try: fixture = open_method(full_path, 'r') if label_found: fixture.close() - print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." % - (fixture_name, humanize(fixture_dir))) + self.stderr.write(self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting.\n" % + (fixture_name, humanize(fixture_dir)))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) return else: fixture_count += 1 objects_in_fixture = 0 - if verbosity > 0: - print "Installing %s fixture '%s' from %s." % \ - (format, fixture_name, humanize(fixture_dir)) + loaded_objects_in_fixture = 0 + if verbosity >= 2: + self.stdout.write("Installing %s fixture '%s' from %s.\n" % \ + (format, fixture_name, humanize(fixture_dir))) try: objects = serializers.deserialize(format, fixture, using=using) for obj in objects: + objects_in_fixture += 1 if router.allow_syncdb(using, obj.object.__class__): - objects_in_fixture += 1 + loaded_objects_in_fixture += 1 models.add(obj.object.__class__) obj.save(using=using) - object_count += objects_in_fixture + loaded_object_count += loaded_objects_in_fixture + fixture_object_count += objects_in_fixture label_found = True except (SystemExit, KeyboardInterrupt): raise @@ -179,7 +183,7 @@ class Command(BaseCommand): if show_traceback: traceback.print_exc() else: - sys.stderr.write( + self.stderr.write( self.style.ERROR("Problem installing fixture '%s': %s\n" % (full_path, ''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))))) @@ -189,25 +193,25 @@ class Command(BaseCommand): # If the fixture we loaded contains 0 objects, assume that an # error was encountered during fixture loading. if objects_in_fixture == 0: - sys.stderr.write( - self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" % + self.stderr.write( + self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)\n" % (fixture_name))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) return except Exception, e: - if verbosity > 1: - print "No %s fixture '%s' in %s." % \ - (format, fixture_name, humanize(fixture_dir)) + if verbosity >= 2: + self.stdout.write("No %s fixture '%s' in %s.\n" % \ + (format, fixture_name, humanize(fixture_dir))) # If we found even one object in a fixture, we need to reset the # database sequences. - if object_count > 0: + if loaded_object_count > 0: sequence_sql = connection.ops.sequence_reset_sql(self.style, models) if sequence_sql: - if verbosity > 1: - print "Resetting sequences" + if verbosity >= 2: + self.stdout.write("Resetting sequences\n") for line in sequence_sql: cursor.execute(line) @@ -215,12 +219,17 @@ class Command(BaseCommand): transaction.commit(using=using) transaction.leave_transaction_management(using=using) - if object_count == 0: - if verbosity > 0: - print "No fixtures found." + if fixture_object_count == 0: + if verbosity >= 1: + self.stdout.write("No fixtures found.\n") else: - if verbosity > 0: - print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count) + if verbosity >= 1: + if fixture_object_count == loaded_object_count: + self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % ( + loaded_object_count, fixture_count)) + else: + self.stdout.write("Installed %d object(s) (of %d) from %d fixture(s)\n" % ( + loaded_object_count, fixture_object_count, fixture_count)) # Close the DB connection. This is required as a workaround for an # edge case in MySQL: if the same connection is used to diff --git a/django/core/management/commands/syncdb.py b/django/core/management/commands/syncdb.py index 6f1a198653..835e06f24a 100644 --- a/django/core/management/commands/syncdb.py +++ b/django/core/management/commands/syncdb.py @@ -77,10 +77,12 @@ class Command(NoArgsCommand): ) # Create the tables for each model + if verbosity >= 1: + print "Creating tables ..." for app_name, model_list in manifest.items(): for model in model_list: # Create the model's database table, if it doesn't already exist. - if verbosity >= 2: + if verbosity >= 3: print "Processing %s.%s model" % (app_name, model._meta.object_name) sql, references = connection.creation.sql_create_model(model, self.style, seen_models) seen_models.add(model) @@ -108,12 +110,14 @@ class Command(NoArgsCommand): # Install custom SQL for the app (but only if this # is a model we've just created) + if verbosity >= 1: + print "Installing custom SQL ..." for app_name, model_list in manifest.items(): for model in model_list: if model in created_models: custom_sql = custom_sql_for_model(model, self.style, connection) if custom_sql: - if verbosity >= 1: + if verbosity >= 2: print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name) try: for sql in custom_sql: @@ -128,16 +132,18 @@ class Command(NoArgsCommand): else: transaction.commit_unless_managed(using=db) else: - if verbosity >= 2: + if verbosity >= 3: print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name) + if verbosity >= 1: + print "Installing indexes ..." # Install SQL indicies for all newly created models for app_name, model_list in manifest.items(): for model in model_list: if model in created_models: index_sql = connection.creation.sql_indexes_for_model(model, self.style) if index_sql: - if verbosity >= 1: + if verbosity >= 2: print "Installing index for %s.%s model" % (app_name, model._meta.object_name) try: for sql in index_sql: diff --git a/django/core/management/commands/testserver.py b/django/core/management/commands/testserver.py index 6c75a3e2b6..d3d9698c9a 100644 --- a/django/core/management/commands/testserver.py +++ b/django/core/management/commands/testserver.py @@ -4,6 +4,8 @@ from optparse import make_option class Command(BaseCommand): option_list = BaseCommand.option_list + ( + make_option('--noinput', action='store_false', dest='interactive', default=True, + help='Tells Django to NOT prompt the user for input of any kind.'), make_option('--addrport', action='store', dest='addrport', type='string', default='', help='port number or ipaddr:port to run the server on'), @@ -18,10 +20,11 @@ class Command(BaseCommand): from django.db import connection verbosity = int(options.get('verbosity', 1)) + interactive = options.get('interactive', True) addrport = options.get('addrport') # Create a test database. - db_name = connection.creation.create_test_db(verbosity=verbosity) + db_name = connection.creation.create_test_db(verbosity=verbosity, autoclobber=not interactive) # Import the fixture data into the test database. call_command('loaddata', *fixture_labels, **{'verbosity': verbosity}) |