(self, **options)
| 59 | ) |
| 60 | |
| 61 | def handle(self, **options): |
| 62 | self.verbosity = options["verbosity"] |
| 63 | self.interactive = options["interactive"] |
| 64 | app_label = options["app_label"] |
| 65 | start_migration_name = options["start_migration_name"] |
| 66 | migration_name = options["migration_name"] |
| 67 | no_optimize = options["no_optimize"] |
| 68 | squashed_name = options["squashed_name"] |
| 69 | include_header = options["include_header"] |
| 70 | # Validate app_label. |
| 71 | try: |
| 72 | apps.get_app_config(app_label) |
| 73 | except LookupError as err: |
| 74 | raise CommandError(str(err)) |
| 75 | # Load the current graph state, check the app and migration they asked |
| 76 | # for exists. |
| 77 | loader = MigrationLoader(None) |
| 78 | if app_label not in loader.migrated_apps: |
| 79 | raise CommandError( |
| 80 | "App '%s' does not have migrations (so squashmigrations on " |
| 81 | "it makes no sense)" % app_label |
| 82 | ) |
| 83 | |
| 84 | migration = self.find_migration(loader, app_label, migration_name) |
| 85 | |
| 86 | # Work out the list of predecessor migrations |
| 87 | migrations_to_squash = [ |
| 88 | loader.get_migration(al, mn) |
| 89 | for al, mn in loader.graph.forwards_plan( |
| 90 | (migration.app_label, migration.name) |
| 91 | ) |
| 92 | if al == migration.app_label |
| 93 | ] |
| 94 | |
| 95 | if start_migration_name: |
| 96 | start_migration = self.find_migration( |
| 97 | loader, app_label, start_migration_name |
| 98 | ) |
| 99 | start = loader.get_migration( |
| 100 | start_migration.app_label, start_migration.name |
| 101 | ) |
| 102 | try: |
| 103 | start_index = migrations_to_squash.index(start) |
| 104 | migrations_to_squash = migrations_to_squash[start_index:] |
| 105 | except ValueError: |
| 106 | raise CommandError( |
| 107 | "The migration '%s' cannot be found. Maybe it comes after " |
| 108 | "the migration '%s'?\n" |
| 109 | "Have a look at:\n" |
| 110 | " python manage.py showmigrations %s\n" |
| 111 | "to debug this issue." % (start_migration, migration, app_label) |
| 112 | ) |
| 113 | |
| 114 | # Tell them what we're doing and optionally ask if we should proceed |
| 115 | if self.verbosity > 0 or self.interactive: |
| 116 | self.stdout.write( |
| 117 | self.style.MIGRATE_HEADING("Will squash the following migrations:") |
| 118 | ) |
nothing calls this directly
no test coverage detected