Fixed #28363 -- Allowed naming the migration generated by squashmigrations.

This commit is contained in:
Melvyn Sopacua 2017-02-20 15:45:20 +01:00 committed by Tim Graham
parent 5ccbcc5bf6
commit 5bb9b9a388
5 changed files with 49 additions and 3 deletions

View File

@ -32,6 +32,10 @@ class Command(BaseCommand):
'--noinput', '--no-input', action='store_false', dest='interactive',
help='Tells Django to NOT prompt the user for input of any kind.',
)
parser.add_argument(
'--squashed-name', dest='squashed_name',
help='Sets the name of the new squashed migration.',
)
def handle(self, **options):
@ -41,6 +45,7 @@ class Command(BaseCommand):
start_migration_name = options['start_migration_name']
migration_name = options['migration_name']
no_optimize = options['no_optimize']
squashed_name = options['squashed_name']
# Load the current graph state, check the app and migration they asked for exists
loader = MigrationLoader(connections[DEFAULT_DB_ALIAS])
@ -154,9 +159,17 @@ class Command(BaseCommand):
"replaces": replaces,
})
if start_migration_name:
new_migration = subclass("%s_squashed_%s" % (start_migration.name, migration.name), app_label)
if squashed_name:
# Use the name from --squashed-name.
prefix, _ = start_migration.name.split('_', 1)
name = '%s_%s' % (prefix, squashed_name)
else:
new_migration = subclass("0001_squashed_%s" % migration.name, app_label)
# Generate a name.
name = '%s_squashed_%s' % (start_migration.name, migration.name)
new_migration = subclass(name, app_label)
else:
name = '0001_%s' % (squashed_name or 'squashed_%s' % migration.name)
new_migration = subclass(name, app_label)
new_migration.initial = True
# Write out the new migration file

View File

@ -1132,6 +1132,13 @@ behavior, as optimization is meant to be safe.
Suppresses all user prompts.
.. django-admin-option:: --squashed-name SQUASHED_NAME
.. versionadded:: 2.0
Sets the name of the squashed migration. When omitted, the name is based on the
first and last migration, with ``_squashed_`` in between.
``startapp``
------------

View File

@ -219,7 +219,8 @@ Management Commands
Migrations
~~~~~~~~~~
* ...
* The new :option:`squashmigrations --squashed-name` option allows naming
the squashed migration.
Models
~~~~~~

View File

@ -605,6 +605,9 @@ work::
all instances of the codebase have applied the migrations you squashed,
you can delete them.
Use the :option:`squashmigrations --squashed-name` option if you want to set
the name of the squashed migration rather than use an autogenerated one.
Note that model interdependencies in Django can get very complex, and squashing
may result in migrations that do not run; either mis-optimized (in which case
you can try again with ``--no-optimize``, though you should also report an issue),

View File

@ -1356,3 +1356,25 @@ class SquashMigrationsTests(MigrationTestBase):
)
with self.assertRaisesMessage(CommandError, msg):
call_command("squashmigrations", "migrations", "0003", "0002", interactive=False, verbosity=0)
def test_squashed_name_with_start_migration_name(self):
"""--squashed-name specifies the new migration's name."""
squashed_name = 'squashed_name'
with self.temporary_migration_module(module='migrations.test_migrations') as migration_dir:
call_command(
'squashmigrations', 'migrations', '0001', '0002',
squashed_name=squashed_name, interactive=False, verbosity=0,
)
squashed_migration_file = os.path.join(migration_dir, '0001_%s.py' % squashed_name)
self.assertTrue(os.path.exists(squashed_migration_file))
def test_squashed_name_without_start_migration_name(self):
"""--squashed-name also works if a start migration is omitted."""
squashed_name = 'squashed_name'
with self.temporary_migration_module(module="migrations.test_migrations") as migration_dir:
call_command(
'squashmigrations', 'migrations', '0001',
squashed_name=squashed_name, interactive=False, verbosity=0,
)
squashed_migration_file = os.path.join(migration_dir, '0001_%s.py' % squashed_name)
self.assertTrue(os.path.exists(squashed_migration_file))