2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
title: Recovering deleted Wagtail pages and Django models
|
|
|
|
class: text-center
|
|
|
|
highlighter: shiki
|
|
|
|
transition: slide-left
|
2024-04-18 17:05:39 +01:00
|
|
|
mdc: true
|
|
|
|
themeConfig:
|
|
|
|
primary: '#fd5765'
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
# Recovering [deleted]{style="color: #fd5765"} Wagtail pages and/or Django models
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
### Jake Howard{style="color: #e85537;" .mt-10 }
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
<ul class="list-none! text-sm [&>li]:m-0! mt-1 uppercase">
|
|
|
|
<li>Senior Systems Engineer @ Torchbox</li>
|
2024-05-29 14:42:49 +01:00
|
|
|
<li>Core Team, Security Team & Performance Working Group @ Wagtail</li>
|
2024-04-18 17:05:39 +01:00
|
|
|
</ul>
|
|
|
|
|
|
|
|
<ul class="list-none! text-sm [&>li]:m-0! mt-3">
|
|
|
|
<li><mdi-earth /> theorangeone.net</li>
|
|
|
|
<li><mdi-twitter /> @RealOrangeOne</li>
|
|
|
|
<li><mdi-github /> @RealOrangeOne</li>
|
|
|
|
<li><mdi-mastodon /> @jake@theorangeone.net</li>
|
|
|
|
</ul>
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
---
|
|
|
|
layout: cover
|
2024-05-17 12:37:47 +01:00
|
|
|
background: /intranet.png
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
# Setting the scene
|
|
|
|
|
|
|
|
---
|
|
|
|
layout: cover
|
2024-05-17 12:37:47 +01:00
|
|
|
background: /site-history.png
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
# Site history report
|
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
---
|
|
|
|
layout: image
|
|
|
|
image: /chat.png
|
|
|
|
backgroundSize: contain
|
|
|
|
---
|
|
|
|
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: section
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
# Restoring from backups
|
|
|
|
|
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: section
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
# _Partially_ restoring from backups
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: section
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
## 1.
|
|
|
|
# Spin up a database backup
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: section
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
## 2.
|
|
|
|
# Locate the page models
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-06-09 21:33:13 +01:00
|
|
|
<div class="pt-5 text-left">
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
```python
|
|
|
|
from wagtail.models import Page
|
|
|
|
|
|
|
|
sysadmin_page = Page.objects.get(id=91)
|
|
|
|
|
|
|
|
child_pages = sysadmin_page.get_descendants()
|
|
|
|
```
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
---
|
|
|
|
layout: section
|
|
|
|
---
|
|
|
|
|
|
|
|
## 3.
|
|
|
|
# Locate what was deleted
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-06-09 21:33:13 +01:00
|
|
|
<div class="pt-5 text-left">
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
```python
|
|
|
|
from django.contrib.admin.utils import NestedObjects
|
|
|
|
|
|
|
|
collector = NestedObjects()
|
|
|
|
collector.collect(list(child_pages) + [sysadmin_page])
|
|
|
|
```
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
---
|
|
|
|
layout: section
|
|
|
|
---
|
|
|
|
|
2024-06-09 21:33:13 +01:00
|
|
|
## 4.
|
|
|
|
# Serialize
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-06-09 21:33:13 +01:00
|
|
|
<div class="pt-5 text-left">
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
```python {all|3-5|all}
|
2024-04-05 18:01:50 +01:00
|
|
|
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
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
<style>
|
|
|
|
pre.shiki {
|
2024-06-09 21:33:13 +01:00
|
|
|
font-size: 0.8rem !important;
|
|
|
|
line-height: 18px;
|
2024-05-10 17:53:24 +01:00
|
|
|
}
|
|
|
|
</style>
|
|
|
|
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: section
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
## 4a.
|
2024-05-17 12:37:47 +01:00
|
|
|
# [De]{.italic}serialize
|
|
|
|
|
|
|
|
### `manage.py loaddata`
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
---
|
|
|
|
layout: center
|
|
|
|
---
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
# `restore-deleted-pages.py`
|
|
|
|
|
|
|
|
```python {all}{lines:true}
|
|
|
|
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
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
2024-06-09 21:33:13 +01:00
|
|
|
<style>
|
|
|
|
pre.shiki {
|
|
|
|
font-size: 0.7rem !important;
|
|
|
|
line-height: 17px;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
---
|
2024-05-17 12:37:47 +01:00
|
|
|
layout: fact
|
2024-05-10 17:53:24 +01:00
|
|
|
---
|
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
### 5.
|
2024-05-10 17:53:24 +01:00
|
|
|
# **Test!**
|
2024-04-05 18:01:50 +01:00
|
|
|
|
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: image-right
|
|
|
|
image: /red-button.png
|
|
|
|
class: flex justify-center flex-col items-center
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
2024-05-10 17:53:24 +01:00
|
|
|
### 6.
|
|
|
|
# Showtime!
|
2024-04-05 18:01:50 +01:00
|
|
|
|
2024-05-17 12:37:47 +01:00
|
|
|
---
|
|
|
|
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`
|
|
|
|
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
2024-05-10 17:53:24 +01:00
|
|
|
layout: cover
|
2024-05-17 12:37:47 +01:00
|
|
|
background: /sysadmin.png
|
2024-04-05 18:01:50 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
# Conclusion
|
2024-05-10 17:53:24 +01:00
|
|
|
|
|
|
|
---
|
|
|
|
layout: end
|
|
|
|
---
|
2024-05-10 17:55:23 +01:00
|
|
|
|
|
|
|
END
|