title |
class |
highlighter |
transition |
mdc |
themeConfig |
addons |
Recovering deleted Wagtail pages and Django models |
text-center |
shiki |
slide-left |
true |
|
|
Recovering [deleted]{style="color: #fd5765"} Wagtail pages and/or Django models
Jake Howard
- Senior Systems Engineer @ Torchbox
- 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!
- Backup!
- Transfer
deleted-models.json
to server
loaddata
checktree
update_index
rebuild_reference_index
layout: cover
background: /sysadmin.png
Conclusion
layout: end
END