Open benjaoming opened 5 months ago
Currently, there seems to be no real benefit, but we might be able to create a benefit in the future.
Here's a migration that gets it done:
import json from django.contrib.contenttypes.models import ContentType from django.core.serializers.json import DjangoJSONEncoder from django.db import migrations import wagtail.blocks import wagtail.fields def page_to_streamfield(page): changed = False try: json.loads(page.description) except ValueError: page.description = json.dumps( [{"type": "rich_text", "value": page.description}], ) changed = True else: # It's already valid JSON. Leave it. pass return page, changed def pagerevision_to_streamfield(revision_data): changed = False description = revision_data.get("description") if description: try: json.loads(description) except ValueError: revision_data["description"] = json.dumps( [{ "value": description, "type": "rich_text" }], cls=DjangoJSONEncoder) changed = True else: # It's already valid JSON. Leave it. pass return revision_data, changed def page_to_richtext(page): changed = False if page.description: try: description_data = json.loads(page.description) except ValueError: # It's not apparently a StreamField. Leave it. pass else: page.description = "".join([ child["value"] for child in description_data if child["type"] == "rich_text" ]) changed = True return page, changed def pagerevision_to_richtext(revision_data): changed = False description = revision_data.get("description", "definitely non-JSON string") if description: try: description_data = json.loads(description) except ValueError: # It's not apparently a StreamField. Leave it. pass else: raw_text = "".join([ child["value"] for child in description_data if child["type"] == "rich_text" ]) revision_data["body"] = raw_text changed = True return revision_data, changed def convert(apps, schema_editor, page_converter, pagerevision_converter): WikiPage = apps.get_model("wiki", "WikiPage") content_type = ContentType.objects.get_for_model(WikiPage) Revision = apps.get_model("wagtailcore", "Revision") for page in WikiPage.objects.all(): page, changed = page_converter(page) if changed: page.save() for revision in Revision.objects.filter( content_type_id=content_type.pk, object_id=page.pk ): revision_data = revision.content revision_data, changed = pagerevision_converter(revision_data) if changed: revision.content = revision_data revision.save() def convert_to_streamfield(apps, schema_editor): return convert(apps, schema_editor, page_to_streamfield, pagerevision_to_streamfield) def convert_to_richtext(apps, schema_editor): return convert(apps, schema_editor, page_to_richtext, pagerevision_to_richtext) class Migration(migrations.Migration): dependencies = [ # leave the dependency line from the generated migration intact! ("wiki", "0005_alter_wikiindexpage_body"), ("wagtailcore", "0076_modellogentry_revision"), ] operations = [ migrations.RunPython( convert_to_streamfield, convert_to_richtext, ), # leave the generated AlterField intact! migrations.AlterField( model_name="WikiPage", name="description", field=wagtail.fields.StreamField( [("rich_text", wagtail.blocks.RichTextBlock())], ), ), ]
Currently, there seems to be no real benefit, but we might be able to create a benefit in the future.
Here's a migration that gets it done: