Skip to content

Commit 03d72bc

Browse files
authored
DBC22-6032: reordering advisory/bulletin under index page (#1295)
1 parent aa6fed0 commit 03d72bc

6 files changed

Lines changed: 702 additions & 8 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Generated by Django 5.2.12 on 2026-04-14 15:05
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('cms', '0024_emergencyalertdetail_emergencyalert_detail_page'),
11+
('wagtailcore', '0096_referenceindex_referenceindex_source_object_and_more'),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='AdvisoryIndexPage',
17+
fields=[
18+
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
19+
],
20+
options={
21+
'abstract': False,
22+
},
23+
bases=('wagtailcore.page',),
24+
),
25+
migrations.CreateModel(
26+
name='BulletinIndexPage',
27+
fields=[
28+
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
29+
],
30+
options={
31+
'abstract': False,
32+
},
33+
bases=('wagtailcore.page',),
34+
),
35+
migrations.AlterModelOptions(
36+
name='advisory',
37+
options={'ordering': ['path'], 'verbose_name_plural': 'advisories'},
38+
),
39+
migrations.AlterModelOptions(
40+
name='bulletin',
41+
options={'ordering': ['path'], 'verbose_name_plural': 'bulletins'},
42+
),
43+
]

src/backend/apps/cms/models.py

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,96 @@
2727
border on the left).
2828
'''
2929

30+
def reparent_orphan_advisories():
31+
"""
32+
Move all Advisory pages that are not children of AdvisoryIndexPage
33+
to be children of the existing AdvisoryIndexPage.
34+
"""
35+
index = AdvisoryIndexPage.objects.first()
36+
if not index:
37+
return
38+
39+
orphans = []
40+
for advisory in Advisory.objects.all():
41+
if advisory.get_parent().specific_class != AdvisoryIndexPage:
42+
orphans.append(advisory)
43+
44+
if not orphans:
45+
return
46+
47+
for advisory in orphans:
48+
advisory.move(index, pos="first-child") # Use "first-child" for newest on top
49+
50+
def reparent_orphan_bulletins():
51+
"""
52+
Move all Bulletin pages that are not children of BulletinIndexPage
53+
to be children of the existing BulletinIndexPage.
54+
"""
55+
index = BulletinIndexPage.objects.first()
56+
if not index:
57+
return
58+
59+
orphans = []
60+
for bulletin in Bulletin.objects.all():
61+
if bulletin.get_parent().specific_class != BulletinIndexPage:
62+
orphans.append(bulletin)
63+
64+
if not orphans:
65+
return
66+
67+
for bulletin in orphans:
68+
bulletin.move(index, pos="first-child") # Use "first-child" for newest on top
69+
70+
def get_or_create_advisory_index():
71+
index = AdvisoryIndexPage.objects.first()
72+
73+
if index:
74+
actual_children_count = index.get_children().count()
75+
76+
if index.numchild != actual_children_count:
77+
index.numchild = actual_children_count
78+
index.save(update_fields=["numchild"])
79+
reparent_orphan_advisories()
80+
81+
return index
82+
83+
root = Page.get_first_root_node()
84+
85+
index = AdvisoryIndexPage(
86+
title="Advisories",
87+
slug="advisories",
88+
)
89+
90+
root.add_child(instance=index)
91+
index.save_revision().publish()
92+
93+
return index
94+
95+
def get_or_create_bulletin_index():
96+
index = BulletinIndexPage.objects.first()
97+
if index:
98+
actual_children_count = index.get_children().count()
99+
100+
if index.numchild != actual_children_count:
101+
index.numchild = actual_children_count
102+
index.save(update_fields=["numchild"])
103+
104+
reparent_orphan_bulletins()
105+
return index
106+
107+
# create properly
108+
root = Page.get_first_root_node()
109+
110+
index = BulletinIndexPage(
111+
title="Bulletins",
112+
slug="bulletins",
113+
)
114+
115+
root.add_child(instance=index)
116+
index.save_revision().publish()
117+
118+
return index
119+
30120
class FlexibleMultiPolygonField(MultiPolygonField):
31121
def to_python(self, value):
32122
if not value:
@@ -79,6 +169,12 @@ class RichContent(blocks.StreamBlock):
79169
template='cms/callout.html')
80170

81171

172+
class AdvisoryIndexPage(Page):
173+
parent_page_types = ["wagtailcore.Page"]
174+
subpage_types = ["cms.Advisory"]
175+
176+
max_count = 1
177+
82178
class Advisory(Page, BaseModel):
83179
page_body = "Use this page for creating advisories."
84180
teaser = models.CharField(max_length=250, blank=True)
@@ -92,7 +188,7 @@ def rendered_body(self):
92188
api_fields = [
93189
APIField('rendered_body'),
94190
]
95-
191+
parent_page_types = ["cms.AdvisoryIndexPage"]
96192
subpage_types = [
97193
'cms.SubPage',
98194
]
@@ -144,6 +240,11 @@ def save(self, *args, **kwargs):
144240
super().save(log_action=None, *args, **kwargs)
145241
cache.delete(CacheKey.ADVISORY_LIST)
146242

243+
class BulletinIndexPage(Page):
244+
parent_page_types = ["wagtailcore.Page"]
245+
subpage_types = ["cms.Bulletin"]
246+
247+
max_count = 1
147248

148249
class Bulletin(Page, BaseModel):
149250
page_body = "Use this page for creating bulletins."
@@ -159,7 +260,7 @@ def rendered_body(self):
159260
api_fields = [
160261
APIField('rendered_body'),
161262
]
162-
263+
parent_page_types = ["cms.BulletinIndexPage"]
163264
subpage_types = [
164265
'cms.SubPage',
165266
]

0 commit comments

Comments
 (0)