@@ -93,6 +93,12 @@ def add_arguments(self, parser):
93
93
"resulting operations."
94
94
),
95
95
)
96
+ parser .add_argument (
97
+ "--replace-all" ,
98
+ action = "store_true" ,
99
+ dest = "replace_all" ,
100
+ help = "Create fresh migrations that replaces existing ones." ,
101
+ )
96
102
97
103
@property
98
104
def log_output (self ):
@@ -118,6 +124,7 @@ def handle(self, *app_labels, **options):
118
124
self .dry_run = True
119
125
self .scriptable = options ["scriptable" ]
120
126
self .update = options ["update" ]
127
+ self .replace_all = options ["replace_all" ]
121
128
# If logs and prompts are diverted to stderr, remove the ERROR style.
122
129
if self .scriptable :
123
130
self .stderr .style_func = None
@@ -209,11 +216,28 @@ def handle(self, *app_labels, **options):
209
216
log = self .log ,
210
217
)
211
218
# Set up autodetector
212
- autodetector = MigrationAutodetector (
213
- loader .project_state (),
214
- ProjectState .from_apps (apps ),
215
- questioner ,
216
- )
219
+ if self .replace_all :
220
+ replace_list = [migration for migration in loader .graph .nodes .values ()]
221
+ temp_nodes = loader .graph .nodes
222
+
223
+ loader .graph .nodes = {
224
+ k : v for (k , v ) in loader .graph .nodes .items () if k [0 ] not in app_labels
225
+ }
226
+
227
+ autodetector = MigrationAutodetector (
228
+ loader .project_state (),
229
+ ProjectState .from_apps (apps ),
230
+ questioner ,
231
+ )
232
+
233
+ loader .graph .nodes = temp_nodes
234
+
235
+ else :
236
+ autodetector = MigrationAutodetector (
237
+ loader .project_state (),
238
+ ProjectState .from_apps (apps ),
239
+ questioner ,
240
+ )
217
241
218
242
# If they want to make an empty migration, make one for each app
219
243
if self .empty :
@@ -255,6 +279,19 @@ def handle(self, *app_labels, **options):
255
279
else :
256
280
if self .update :
257
281
self .write_to_last_migration_files (changes )
282
+ elif self .replace_all :
283
+ for app_label , app_migrations in changes .items ():
284
+ for app_migration in app_migrations :
285
+ app_migration .replaces = [
286
+ (migration .app_label , migration .name )
287
+ for migration in replace_list
288
+ if migration .app_label == app_label
289
+ ]
290
+ app_migration .dependencies = [
291
+ dependency
292
+ for dependency in app_migration .dependencies
293
+ if dependency not in app_migration .replaces
294
+ ]
258
295
else :
259
296
self .write_migration_files (changes )
260
297
if check_changes :
@@ -347,6 +384,8 @@ def write_migration_files(self, changes, update_previous_migration_paths=None):
347
384
# directory, or an absolute path otherwise.
348
385
migration_string = self .get_relative_path (writer .path )
349
386
self .log (" %s\n " % self .style .MIGRATE_LABEL (migration_string ))
387
+ if self .replace_all :
388
+ self .stdout .write (" Replaces '%s'." % migration .replaces )
350
389
for operation in migration .operations :
351
390
self .log (" - %s" % operation .describe ())
352
391
if self .scriptable :
0 commit comments