general: fix site import when link cells refer to future cells (#8598)

This commit is contained in:
Frédéric Péters 2016-03-06 16:00:53 +01:00
parent e674108bee
commit 6abb1b30c0
2 changed files with 72 additions and 9 deletions

View File

@ -65,7 +65,15 @@ def element_is_visible(element, user=None):
return len(set(page_groups).intersection(user.groups.all())) > 0
class PageManager(models.Manager):
def get_by_natural_key(self, path):
parts = [x for x in path.strip('/').split('/') if x] or ['index']
return self.get(slug=parts[-1])
class Page(models.Model):
objects = PageManager()
title = models.CharField(_('Title'), max_length=50)
slug = models.SlugField(_('Slug'))
template_name = models.CharField(_('Template'), max_length=50)
@ -86,6 +94,9 @@ class Page(models.Model):
def __unicode__(self):
return self.title
def natural_key(self):
return (self.get_online_url().strip('/'), )
def save(self, *args, **kwargs):
if not self.order:
max_order = Page.objects.all().aggregate(Max('order')).get('order__max') or 0
@ -182,13 +193,11 @@ class Page(models.Model):
def get_serialized_page(self):
cells = CellBase.get_cells(page_id=self.id)
serialized_page = json.loads(serializers.serialize('json', [self]))[0]
del serialized_page['pk']
serialized_page = json.loads(serializers.serialize('json', [self],
use_natural_foreign_keys=True, use_natural_primary_keys=True))[0]
del serialized_page['model']
del serialized_page['fields']['parent']
if self.parent_id:
serialized_page['parent_slug'] = self.parent.slug
serialized_page['cells'] = json.loads(serializers.serialize('json', cells))
serialized_page['cells'] = json.loads(serializers.serialize('json',
cells, use_natural_foreign_keys=True, use_natural_primary_keys=True))
for cell in serialized_page['cells']:
del cell['pk']
del cell['fields']['page']
@ -202,20 +211,25 @@ class Page(models.Model):
page = [x for x in serializers.deserialize('json', json.dumps([json_page]))][0]
page.save()
for cell in json_page.get('cells'):
cell['fields']['page'] = page.object.id
cell['fields']['page'] = page.object.natural_key()
# if there were cells, remove them
for cell in CellBase.get_cells(page_id=page.object.id):
cell.delete()
@classmethod
def load_serialized_cells(cls, cells):
# load new cells
for cell in serializers.deserialize('json', json.dumps(json_page.get('cells'))):
for cell in serializers.deserialize('json', json.dumps(cells)):
cell.save()
@classmethod
def load_serialized_pages(cls, json_site):
cells = []
for json_page in json_site:
cls.load_serialized_page(json_page)
cells.extend(json_page.get('cells'))
cls.load_serialized_cells(cells)
# 2nd pass to set parents
for json_page in json_site:

View File

@ -1,7 +1,7 @@
import pytest
from django.contrib.auth.models import User, Group
from combo.data.models import Page
from combo.data.models import Page, CellBase, TextCell, LinkCell
pytestmark = pytest.mark.django_db
@ -112,3 +112,52 @@ def test_page_visibility():
assert not page.is_visible()
assert page.is_visible(user1)
assert not page.is_visible(user2)
def test_import_export_pages():
page = Page(title='foo', slug='foo', order=0)
page.save()
cell = TextCell(page=page, text='foo', order=0)
cell.save()
page2 = Page(title='bar', slug='bar', order=1, parent=page)
page2.save()
cell = TextCell(page=page2, text='bar', order=0)
cell.save()
site_export = [x.get_serialized_page() for x in Page.objects.all()]
Page.objects.all().delete()
Page.load_serialized_pages(site_export)
new_page_1 = Page.objects.all().order_by('order')[0]
new_page_2 = Page.objects.all().order_by('order')[1]
assert new_page_1.title == 'foo'
assert new_page_2.title == 'bar'
assert len(CellBase.get_cells(page_id=new_page_1.id)) == 1
assert isinstance(CellBase.get_cells(page_id=new_page_1.id)[0], TextCell)
assert CellBase.get_cells(page_id=new_page_1.id)[0].text == 'foo'
def test_import_export_pages_with_links():
page = Page(title='foo', slug='foo', order=0)
page.save()
page2 = Page(title='bar', slug='bar', order=1)
page2.save()
cell = LinkCell(page=page, title='bar', link_page=page2, order=1)
cell.save()
cell2 = LinkCell(page=page2, title='foo', link_page=page, order=1)
cell2.save()
site_export = [x.get_serialized_page() for x in Page.objects.all()]
Page.objects.all().delete()
Page.load_serialized_pages(site_export)
new_page_1 = Page.objects.all().order_by('order')[0]
new_page_2 = Page.objects.all().order_by('order')[1]
assert CellBase.get_cells(page_id=new_page_1.id)[0].link_page_id == new_page_2.id
assert CellBase.get_cells(page_id=new_page_2.id)[0].link_page_id == new_page_1.id