summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikuláš Poul <mikulas.poul@xelix.com>2025-03-23 15:30:24 +0000
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-04-16 10:20:49 +0200
commit494d2dc316fc1d849b6a1af97575d293f856a84c (patch)
treec4b1dffa9787ffbdb31d3549e1b262ded1ba1066
parent5020a9d43a9ebd5f20f9a77e5fed424023facb15 (diff)
Fixed #36274 -- Added support for run_before and atomic in MigrationWriter.
-rw-r--r--AUTHORS1
-rw-r--r--django/db/migrations/writer.py11
-rw-r--r--tests/migrations/test_writer.py39
3 files changed, 49 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index 637ca41ad7..b22af9bccb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -751,6 +751,7 @@ answer newbie questions, and generally made Django that much better:
Mikhail Korobov <kmike84@googlemail.com>
Mikko Hellsing <mikko@sorl.net>
Mikołaj Siedlarek <mikolaj.siedlarek@gmail.com>
+ Mikuláš Poul <mikulaspoul@gmail.com>
milkomeda
Milton Waddams
mitakummaa@gmail.com
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index 3dd3014355..e2befd4d4e 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -131,6 +131,8 @@ class MigrationWriter:
items = {
"replaces_str": "",
"initial_str": "",
+ "run_before_str": "",
+ "atomic_str": "",
}
imports = set()
@@ -189,11 +191,14 @@ class MigrationWriter:
"then update the\n# RunPython operations to refer to the local "
"versions:\n# %s"
) % "\n# ".join(sorted(migration_imports))
- # If there's a replaces, make a string for it
if self.migration.replaces:
items["replaces_str"] = (
"\n replaces = %s\n" % self.serialize(self.migration.replaces)[0]
)
+ if self.migration.run_before:
+ items["run_before_str"] = (
+ "\n run_before = %s\n" % self.serialize(self.migration.run_before)[0]
+ )
# Hinting that goes into comment
if self.include_header:
items["migration_header"] = MIGRATION_HEADER_TEMPLATE % {
@@ -205,6 +210,8 @@ class MigrationWriter:
if self.migration.initial:
items["initial_str"] = "\n initial = True\n"
+ if not self.migration.atomic:
+ items["atomic_str"] = "\n atomic = False\n"
return MIGRATION_TEMPLATE % items
@@ -305,7 +312,7 @@ MIGRATION_TEMPLATE = """\
%(migration_header)s%(imports)s
class Migration(migrations.Migration):
-%(replaces_str)s%(initial_str)s
+%(replaces_str)s%(initial_str)s%(atomic_str)s%(run_before_str)s
dependencies = [
%(dependencies)s\
]
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index 6e9355d9bc..6afee23da2 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -1178,3 +1178,42 @@ class WriterTests(SimpleTestCase):
output = writer.as_string()
self.assertEqual(output.count("import"), 1)
self.assertIn("from django.db import migrations, models", output)
+
+ def test_run_before(self):
+ for run_before, expected_run_before_str in [
+ ([("foo", "0001_bar")], " run_before = [('foo', '0001_bar')]\n"),
+ (
+ [("foo", "0001_bar"), ("foo", "0002_baz")],
+ " run_before = [('foo', '0001_bar'), ('foo', '0002_baz')]\n",
+ ),
+ ]:
+ with self.subTest(run_before=run_before):
+ migration = type(
+ "Migration",
+ (migrations.Migration,),
+ {"operations": [], "run_before": run_before},
+ )
+ writer = MigrationWriter(migration)
+ output = writer.as_string()
+ self.assertIn(expected_run_before_str, output)
+
+ def test_atomic_is_false(self):
+ migration = type(
+ "Migration",
+ (migrations.Migration,),
+ {"operations": [], "atomic": False},
+ )
+ writer = MigrationWriter(migration)
+ output = writer.as_string()
+ self.assertIn(" atomic = False\n", output)
+
+ def test_default_attributes(self):
+ migration = type("Migration", (migrations.Migration,), {})
+ writer = MigrationWriter(migration)
+ output = writer.as_string()
+ self.assertIn(" dependencies = [\n ]\n", output)
+ self.assertIn(" operations = [\n ]\n", output)
+ self.assertNotIn("atomic", output)
+ self.assertNotIn("initial", output)
+ self.assertNotIn("run_before", output)
+ self.assertNotIn("replaces", output)