1
Fork 0
recovering-deleted-wagtail-.../slides.md

3.6 KiB

title class highlighter transition mdc themeConfig
Recovering deleted Wagtail pages and Django models text-center shiki slide-left true
primary
#fd5765

Recovering [deleted]{style="color: #fd5765"} Wagtail pages and/or Django models

Jake Howard

  • Senior Systems Engineer @ Torchbox
  • Core Team, Security Team & Performance Working Group @ Wagtail
  • theorangeone.net
  • @RealOrangeOne
  • @RealOrangeOne
  • @jake@theorangeone.net

layout: cover background: /intranet.png

Setting the scene


layout: cover background: /site-history.png

Site history report


layout: image image: /chat.png backgroundSize: contain


layout: section

Restoring from backups


layout: section

Partially restoring from backups


layout: section

1.

Spin up a database backup


layout: section

2.

Locate the page models

from wagtail.models import Page

sysadmin_page = Page.objects.get(id=91)

child_pages = sysadmin_page.get_descendants()

layout: section

3.

Locate what was deleted

from django.contrib.admin.utils import NestedObjects

collector = NestedObjects()
collector.collect(list(child_pages) + [sysadmin_page])

layout: section

4.

Serialize

from django.core import serializers

class NoM2MSerializer(Serializer):
    def handle_m2m_field(self, obj, field):
        pass

def get_model_instances():
    for qs in collector.data.values():
        yield from qs

with open("deleted-models.json", "w") as f:
    NoM2MSerializer().serialize(
        get_model_instances(),
        stream=f
    )

layout: section

4a.

[De]{.italic}serialize

manage.py loaddata


layout: center

restore-deleted-pages.py

from django.contrib.admin.utils import NestedObjects
from django.core import serializers

from wagtail.models import Page

class NoM2MSerializer(Serializer):
    def handle_m2m_field(self, obj, field):
        pass

sysadmin_page = Page.objects.get(id=91)

child_pages = sysadmin_page.get_descendants()

collector = NestedObjects()
collector.collect(list(child_pages) + [sysadmin_page])

def get_model_instances():
    for qs in collector.data.values():
        yield from qs

with open("deleted-models.json", "w") as f:
    NoM2MSerializer().serialize(
        get_model_instances(),
        stream=f
    )

layout: fact

5.

Test!


layout: image-right image: /red-button.png class: flex justify-center flex-col items-center

6.

Showtime!


layout: image-right image: https://images.unsplash.com/photo-1622021134395-d26aab83c221?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D class: flex justify-center flex-col text-xl

  1. Backup!
  2. Transfer deleted-models.json to server
  3. loaddata
  4. checktree
  5. update_index
  6. rebuild_reference_index

layout: cover background: /sysadmin.png

Conclusion


layout: end

END