Skip to content

Commit

Permalink
moved data migration logic to new migration
Browse files Browse the repository at this point in the history
  • Loading branch information
gsidebo committed Dec 21, 2020
1 parent b19cf3a commit 189ccbd
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 221 deletions.
104 changes: 2 additions & 102 deletions cms/migrations/0029_setup_course_program_index_pages.py
Original file line number Diff line number Diff line change
@@ -1,113 +1,13 @@
"""
Data migration to ensure the correct state for course/program index pages and
correct depth for course/program detail pages
Data migrations moved to cms/migrations/0046_page_data_migrations.py in response to Page model change
"""
from django.db import migrations
from wagtail.core.models import Page

COURSE_INDEX_PAGE_PROPERTIES = dict(title="Courses")
PROGRAM_INDEX_PAGE_PROPERTIES = dict(title="Programs")


def delete_wagtail_pages(specific_page_cls, filter_dict=None):
"""
Completely deletes Wagtail CMS pages that match a filter. Wagtail overrides standard delete functionality,
making it difficult to actually delete Page objects and get information about what was deleted.
"""
page_ids_to_delete = specific_page_cls.objects.values_list("id", flat=True)
if filter_dict:
page_ids_to_delete = page_ids_to_delete.filter(**filter_dict)
num_pages = len(page_ids_to_delete)
base_pages_qset = Page.objects.filter(id__in=page_ids_to_delete)
if not base_pages_qset.exists():
return 0, {}
base_pages_qset.delete()
return (
num_pages,
{specific_page_cls._meta.label: num_pages}, # pylint: disable=protected-access
)


def get_home_page(apps):
"""
Importing the Site model from the registry means if we access the root page from this
model we will get an instance of the Page with only the basic model methods so we simply extract
the ID of the page and hand it to the Page model imported directly.
"""
Site = apps.get_model("wagtailcore", "Site")
site = Site.objects.filter(is_default_site=True).first()
if not site:
raise Exception(
"A default site is not set up. Please setup a default site before running this migration"
)
if not site.root_page:
raise Exception(
"No root (home) page set up. Please setup a root (home) page for the default site before running this migration"
)
return Page.objects.get(id=site.root_page.id)


def create_index_pages_and_nest_detail(apps, schema_editor):
"""
Create index pages for courses and programs and move the respective
course and program pages under these index pages.
"""
from cms.models import CourseIndexPage, ProgramIndexPage

CoursePage = apps.get_model("cms", "CoursePage")
ProgramPage = apps.get_model("cms", "ProgramPage")

# Home page
home_page = get_home_page(apps)

course_index = CourseIndexPage.objects.first()
if not course_index:
page_obj = CourseIndexPage(**COURSE_INDEX_PAGE_PROPERTIES)
course_index = home_page.add_child(instance=page_obj)
program_index = ProgramIndexPage.objects.first()
if not program_index:
page_obj = ProgramIndexPage(**PROGRAM_INDEX_PAGE_PROPERTIES)
program_index = home_page.add_child(instance=page_obj)
# Move course/program detail pages to be children of the course/program index pages
for page_id in CoursePage.objects.values_list("id", flat=True):
page = Page.objects.get(id=page_id)
page.move(course_index, "last-child")
for page_id in ProgramPage.objects.values_list("id", flat=True):
page = Page.objects.get(id=page_id)
page.move(program_index, "last-child")


def unnest_detail_and_delete_index_pages(apps, schema_editor):
"""
Move course and program pages under the home page and remove index pages.
"""
CourseIndexPage = apps.get_model("cms", "CourseIndexPage")
ProgramIndexPage = apps.get_model("cms", "ProgramIndexPage")
CoursePage = apps.get_model("cms", "CoursePage")
ProgramPage = apps.get_model("cms", "ProgramPage")

# Move course/program detail pages to be children of the home page
home_page = get_home_page(apps)
top_level_child_ids = [child.id for child in home_page.get_children()]
for page_id in CoursePage.objects.values_list("id", flat=True):
if page_id not in top_level_child_ids:
page = Page.objects.get(id=page_id)
page.move(home_page, "last-child")
for page_id in ProgramPage.objects.values_list("id", flat=True):
if page_id not in top_level_child_ids:
page = Page.objects.get(id=page_id)
page.move(home_page, "last-child")
# Remove the course/program index pages
delete_wagtail_pages(ProgramIndexPage)
delete_wagtail_pages(CourseIndexPage)


class Migration(migrations.Migration):

dependencies = [("cms", "0028_course_program_index_pages")]

operations = [
migrations.RunPython(
create_index_pages_and_nest_detail, unnest_detail_and_delete_index_pages
)
migrations.RunPython(migrations.RunPython.noop, migrations.RunPython.noop)
]
65 changes: 6 additions & 59 deletions cms/migrations/0031_setup_catalog_page.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,14 @@
# Generated by Django 2.1.7 on 2019-05-30 09:52
"""
Data migrations moved to cms/migrations/0046_page_data_migrations.py in response to Page model change
"""

from django.db import migrations
from wagtail.core.models import Page

from cms.models import CatalogPage


def get_home_page(apps):
"""
Importing the Site model from the registry means if we access the root page from this
model we will get an instance of the Page with only the basic model methods so we simply extract
the ID of the page and hand it to the Page model imported directly.
"""
Site = apps.get_model("wagtailcore", "Site")
site = Site.objects.filter(is_default_site=True).first()
if not site:
raise Exception(
"A default site is not set up. Please setup a default site before running this migration"
)
if not site.root_page:
raise Exception(
"No root (home) page set up. Please setup a root (home) page for the default site before running this migration"
)
return Page.objects.get(id=site.root_page.id)


def remove_catalog_page(apps, schema_editor):
"""
Remove the catalog page
"""
ContentType = apps.get_model("contenttypes.ContentType")
catalog_content_type, _ = ContentType.objects.get_or_create(
app_label="cms", model="catalogpage"
)
catalog = Page.objects.get(content_type_id=catalog_content_type.id)
if catalog:
catalog.delete()


def create_catalog_page(apps, schema_editor):
"""
Create a catalog page under the home page
"""
ContentType = apps.get_model("contenttypes.ContentType")
catalog_content_type, _ = ContentType.objects.get_or_create(
app_label="cms", model="catalogpage"
)
home_page = get_home_page(apps)

catalog = CatalogPage.objects.first()

if not catalog:
catalog = CatalogPage(
title="Courseware Catalog",
content_type_id=catalog_content_type.id,
slug="catalog",
)
catalog = home_page.add_child(instance=catalog)
catalog.save_revision().publish()


class Migration(migrations.Migration):

dependencies = [("cms", "0030_catalog_page_model")]

operations = [migrations.RunPython(create_catalog_page, remove_catalog_page)]
operations = [
migrations.RunPython(migrations.RunPython.noop, migrations.RunPython.noop)
]
66 changes: 6 additions & 60 deletions cms/migrations/0043_setup_certificate_index_page.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,14 @@
# Generated by Django 2.2.4 on 2019-09-18 07:20
"""
Data migrations moved to cms/migrations/0046_page_data_migrations.py in response to Page model change
"""

from django.db import migrations
from wagtail.core.models import Page

from cms.constants import CERTIFICATE_INDEX_SLUG
from cms.models import CertificateIndexPage


def get_home_page(apps):
"""
Importing the Site model from the registry means if we access the root page from this
model we will get an instance of the Page with only the basic model methods so we simply extract
the ID of the page and hand it to the Page model imported directly.
"""
Site = apps.get_model("wagtailcore", "Site")
site = Site.objects.filter(is_default_site=True).first()
if not site:
raise Exception(
"A default site is not set up. Please setup a default site before running this migration"
)
if not site.root_page:
raise Exception(
"No root (home) page set up. Please setup a root (home) page for the default site before running this migration"
)
return Page.objects.get(id=site.root_page.id)


def remove_index_page(apps, schema_editor):
"""
Remove the certificate index page
"""
ContentType = apps.get_model("contenttypes.ContentType")
index_content_type, _ = ContentType.objects.get_or_create(
app_label="cms", model="certificateindexpage"
)
index_page = Page.objects.get(content_type_id=index_content_type.id)
if index_page:
index_page.delete()


def create_index_page(apps, schema_editor):
"""
Create a certificate index page under the home page
"""
ContentType = apps.get_model("contenttypes.ContentType")
index_content_type, _ = ContentType.objects.get_or_create(
app_label="cms", model="certificateindexpage"
)
home_page = get_home_page(apps)

index_page = CertificateIndexPage.objects.first()

if not index_page:
index_page = CertificateIndexPage(
title="Certificate Index Page",
content_type_id=index_content_type.id,
slug=CERTIFICATE_INDEX_SLUG,
)
index_page = home_page.add_child(instance=index_page)
index_page.save_revision().publish()


class Migration(migrations.Migration):

dependencies = [("cms", "0042_certificate_index_page")]

operations = [migrations.RunPython(create_index_page, remove_index_page)]
operations = [
migrations.RunPython(migrations.RunPython.noop, migrations.RunPython.noop)
]
Loading

0 comments on commit 189ccbd

Please sign in to comment.