From 21027768bea1f4f7a127fe76cd577163f2b6168f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 26 Feb 2021 16:27:15 +0100
Subject: [PATCH 6/7] data: snapshot restore performances (#51472)

---
 combo/data/models.py  | 20 ++++++++++++++------
 tests/test_manager.py |  6 +++---
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/combo/data/models.py b/combo/data/models.py
index 34279aa0..dfa99ac6 100644
--- a/combo/data/models.py
+++ b/combo/data/models.py
@@ -232,6 +232,9 @@ class Page(models.Model):
         return os.path.splitext(self.picture.name)[-1]
 
     def save(self, *args, **kwargs):
+        if 'update_fields' in kwargs:
+            return super().save(*args, **kwargs)
+
         if not self.id:
             self.related_cells = {'cell_types': []}
         if self.order is None:
@@ -493,16 +496,15 @@ class Page(models.Model):
             cell['fields']['groups'] = [
                 [x] for x in cell['fields']['groups'] if isinstance(x, six.string_types)
             ]
-            if snapshot:
-                cell['fields']['page'] = page.object.id
-            else:
-                cell['fields']['page'] = page.object.natural_key()
+            cell['fields']['page'] = page.object.id
 
         # if there were cells, remove them
         # if page was created, do nothing
         if created is False:
-            for cell in CellBase.get_cells(page_id=page.object.id):
-                cell.delete()
+            for klass in get_cell_classes():
+                if klass is None:
+                    continue
+                klass.objects.filter(page=page.object).delete()
         return page.object  # get page out of deserialization object
 
     @classmethod
@@ -615,10 +617,14 @@ class PageSnapshot(models.Model):
     def load_page(self, json_page, snapshot=None):
         try:
             post_save.disconnect(cell_maintain_page_cell_cache)
+            post_delete.disconnect(cell_maintain_page_cell_cache)
+
             page = Page.load_serialized_page(json_page, snapshot=snapshot)
             page.load_serialized_cells(json_page['cells'])
         finally:
             post_save.connect(cell_maintain_page_cell_cache)
+            post_delete.connect(cell_maintain_page_cell_cache)
+
         page.build_cell_cache()
         return page
 
@@ -1990,6 +1996,8 @@ class ConfigJsonCell(JsonCellBase):
 def create_redirects(sender, instance, raw, **kwargs):
     if raw or not instance.id or instance.snapshot_id:
         return
+    if kwargs.get('update_fields') and kwargs['update_fields'] == frozenset({'related_cells'}):
+        return
     try:
         old_page = Page.objects.get(id=instance.id)
     except Page.DoesNotExist:
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 21983c05..1d393711 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -832,7 +832,7 @@ def test_site_export_import_json(app, admin_user):
     resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit()
-        assert len(ctx.captured_queries) in [853, 854]
+        assert len(ctx.captured_queries) in [823, 824]
 
     Page.objects.all().delete()
     assert LinkCell.objects.count() == 0
@@ -841,7 +841,7 @@ def test_site_export_import_json(app, admin_user):
     resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit()
-        assert len(ctx.captured_queries) == 378
+        assert len(ctx.captured_queries) == 364
     assert set(Page.objects.get(slug='one').related_cells['cell_types']) == set(
         ['data_textcell', 'data_linkcell']
     )
@@ -2187,7 +2187,7 @@ def test_page_versionning(app, admin_user):
     resp = resp.click('restore', index=6)
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit().follow()
-        assert len(ctx.captured_queries) == 327
+        assert len(ctx.captured_queries) == 143
 
     resp2 = resp.click('See online')
     assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')
-- 
2.30.0

