Skip to content

Commit e0ce67d

Browse files
kdmccormickclaude
andcommitted
fix(squash): renumber migration after component squash
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 569a2a3 commit e0ce67d

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import re
2+
3+
import django.core.validators
4+
import django.db.models.deletion
5+
from django.db import migrations, models
6+
7+
import openedx_django_lib.fields
8+
9+
10+
def backfill_container_code(apps, schema_editor):
11+
"""
12+
Backfill container_code and learning_package from publishable_entity.
13+
14+
For existing containers, container_code is set to the entity key (the
15+
only identifier available at this point). Future containers will have
16+
container_code set by the caller.
17+
"""
18+
Container = apps.get_model("openedx_content", "Container")
19+
for container in Container.objects.select_related("publishable_entity__learning_package").all():
20+
container.learning_package = container.publishable_entity.learning_package
21+
container.container_code = container.publishable_entity.key
22+
container.save(update_fields=["learning_package", "container_code"])
23+
24+
25+
class Migration(migrations.Migration):
26+
27+
dependencies = [
28+
("openedx_content", "0009_rename_component_local_key_to_component_code"),
29+
]
30+
31+
operations = [
32+
# 1. Add learning_package FK (nullable initially for backfill)
33+
migrations.AddField(
34+
model_name="container",
35+
name="learning_package",
36+
field=models.ForeignKey(
37+
null=True,
38+
on_delete=django.db.models.deletion.CASCADE,
39+
to="openedx_content.learningpackage",
40+
),
41+
),
42+
# 2. Add container_code (nullable initially for backfill)
43+
migrations.AddField(
44+
model_name="container",
45+
name="container_code",
46+
field=openedx_django_lib.fields.MultiCollationCharField(
47+
db_collations={"mysql": "utf8mb4_bin", "sqlite": "BINARY"},
48+
max_length=255,
49+
null=True,
50+
),
51+
),
52+
# 3. Backfill both fields from publishable_entity
53+
migrations.RunPython(backfill_container_code, migrations.RunPython.noop),
54+
# 4. Make both fields non-nullable and add regex validation to container_code
55+
migrations.AlterField(
56+
model_name="container",
57+
name="learning_package",
58+
field=models.ForeignKey(
59+
null=False,
60+
on_delete=django.db.models.deletion.CASCADE,
61+
to="openedx_content.learningpackage",
62+
),
63+
),
64+
migrations.AlterField(
65+
model_name="container",
66+
name="container_code",
67+
field=openedx_django_lib.fields.MultiCollationCharField(
68+
db_collations={"mysql": "utf8mb4_bin", "sqlite": "BINARY"},
69+
max_length=255,
70+
validators=[
71+
django.core.validators.RegexValidator(
72+
re.compile(r"^[a-zA-Z0-9_.-]+\Z"),
73+
"Enter a valid \"code name\" consisting of letters, numbers, "
74+
"underscores, hyphens, or periods.",
75+
"invalid",
76+
),
77+
],
78+
),
79+
),
80+
# 5. Add uniqueness constraint
81+
migrations.AddConstraint(
82+
model_name="container",
83+
constraint=models.UniqueConstraint(
84+
fields=["learning_package", "container_code"],
85+
name="oel_container_uniq_lp_cc",
86+
),
87+
),
88+
]

0 commit comments

Comments
 (0)