page: add a duplicate action (#24526)
This commit is contained in:
parent
09507f8988
commit
6be400fcfc
|
@ -319,3 +319,7 @@ class Map(CellBase):
|
|||
ctx['group_markers'] = self.group_markers
|
||||
ctx['marker_behaviour_onclick'] = self.marker_behaviour_onclick
|
||||
return ctx
|
||||
|
||||
def duplicate_m2m(self, new_cell):
|
||||
# set layers
|
||||
new_cell.layers.set(self.layers.all())
|
||||
|
|
|
@ -436,6 +436,27 @@ class Page(models.Model):
|
|||
cells = CellBase.get_cells(page_id=self.id)
|
||||
return max([self.last_update_timestamp] + [x.last_update_timestamp for x in cells])
|
||||
|
||||
def duplicate(self):
|
||||
# clone current page
|
||||
new_page = copy.deepcopy(self)
|
||||
new_page.pk = None
|
||||
# set title
|
||||
new_page.title = _('Copy of %s') % self.title
|
||||
# reset snapshot
|
||||
new_page.snapshot = None
|
||||
# set order
|
||||
new_page.order = self.order + 1
|
||||
# store new page
|
||||
new_page.save()
|
||||
|
||||
# set groups
|
||||
new_page.groups.set(self.groups.all())
|
||||
|
||||
for cell in self.get_cells():
|
||||
cell.duplicate(page_target=new_page)
|
||||
|
||||
return new_page
|
||||
|
||||
|
||||
class PageSnapshot(models.Model):
|
||||
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True)
|
||||
|
@ -737,6 +758,24 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
|
|||
def import_subobjects(self, cell_json):
|
||||
pass
|
||||
|
||||
def duplicate(self, page_target=None):
|
||||
# clone current cell
|
||||
new_cell = copy.deepcopy(self)
|
||||
new_cell.pk = None
|
||||
# set page
|
||||
new_cell.page = page_target or self.page
|
||||
# store new cell
|
||||
new_cell.save()
|
||||
|
||||
# set groups
|
||||
new_cell.groups.set(self.groups.all())
|
||||
|
||||
if hasattr(self, 'duplicate_m2m'):
|
||||
self.duplicate_m2m(new_cell)
|
||||
|
||||
return new_cell
|
||||
|
||||
|
||||
@register_cell_class
|
||||
class TextCell(CellBase):
|
||||
text = RichTextField(_('Text'), blank=True, null=True)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<li><a href="{% url 'combo-manager-page-history' pk=object.id %}">{% trans 'history' %}</a></li>
|
||||
<li><a download href="{% url 'combo-manager-page-export' pk=object.id %}">{% trans 'export' %}</a></li>
|
||||
<li><a rel="popup" href="{% url 'combo-manager-page-add-child' pk=object.id %}">{% trans 'add a child page' %}</a></li>
|
||||
<li><a href="{% url 'combo-manager-page-duplicate' pk=object.id %}">{% trans 'Duplicate' %}</a></li>
|
||||
<li><a rel="popup" href="{% url 'combo-manager-page-delete' pk=object.id %}">{% trans 'delete' %}</a></li>
|
||||
</ul>
|
||||
</span>
|
||||
|
|
|
@ -54,6 +54,8 @@ urlpatterns = [
|
|||
url(r'^pages/(?P<pk>\w+)/export$', views.page_export,
|
||||
name='combo-manager-page-export'),
|
||||
url(r'^pages/(?P<pk>\w+)/add/$', views.page_add_child, name='combo-manager-page-add-child'),
|
||||
url(r'^pages/(?P<pk>\w+)/duplicate$', views.page_duplicate,
|
||||
name='combo-manager-page-duplicate'),
|
||||
url(r'^pages/(?P<pk>\w+)/history$', views.page_history,
|
||||
name='combo-manager-page-history'),
|
||||
url(r'^pages/(?P<page_pk>\w+)/history/(?P<pk>\w+)/$', views.snapshot_restore,
|
||||
|
|
|
@ -325,6 +325,19 @@ class PageExportView(DetailView):
|
|||
page_export = PageExportView.as_view()
|
||||
|
||||
|
||||
class PageDuplicateView(RedirectView):
|
||||
permanent = False
|
||||
|
||||
def get_redirect_url(self, pk):
|
||||
page = Page.objects.get(pk=pk)
|
||||
new_page = page.duplicate()
|
||||
messages.info(self.request, _('Page %s has been duplicated.') % page.title)
|
||||
return reverse('combo-manager-page-view', kwargs={'pk': new_page.pk})
|
||||
|
||||
|
||||
page_duplicate = PageDuplicateView.as_view()
|
||||
|
||||
|
||||
class PageHistoryView(ListView):
|
||||
model = PageSnapshot
|
||||
template_name = 'combo/page_history.html'
|
||||
|
|
|
@ -440,6 +440,19 @@ def test_site_export_import(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert 'File is not in the expected JSON format.' in resp.text
|
||||
|
||||
|
||||
def test_duplicate_page(app, admin_user):
|
||||
page = Page.objects.create(title='One', slug='one', template_name='standard')
|
||||
TextCell.objects.create(page=page, placeholder='content', text='Foobar', order=0)
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/pages/%s/' % page.pk)
|
||||
resp = resp.click('Duplicate')
|
||||
new_page = Page.objects.latest('pk')
|
||||
assert resp.status_int == 302
|
||||
assert resp.location.endswith('/manage/pages/%s/' % new_page.pk)
|
||||
|
||||
|
||||
def test_add_edit_cell(app, admin_user):
|
||||
Page.objects.all().delete()
|
||||
page = Page(title='One', slug='one', template_name='standard')
|
||||
|
|
|
@ -392,3 +392,13 @@ def test_get_geojson_properties(app, layer, user):
|
|||
features = json.loads(resp.text)['features']
|
||||
assert len(features[0]['properties']['display_fields']) == 1
|
||||
assert features[0]['properties']['layer']['properties'] == ['id']
|
||||
|
||||
|
||||
def test_duplicate(layer):
|
||||
page = Page.objects.create(title='xxx', slug='new', template_name='standard')
|
||||
cell = Map.objects.create(page=page, placeholder='content', order=0, public=True, title='Map')
|
||||
layer.save()
|
||||
cell.layers.add(layer)
|
||||
|
||||
new_cell = cell.duplicate()
|
||||
assert list(new_cell.layers.all()) == [layer]
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.test import override_settings
|
|||
from django.test.client import RequestFactory
|
||||
from django.utils.six import StringIO
|
||||
from django.utils.timezone import now
|
||||
from combo.data.models import Page, CellBase, TextCell, LinkCell
|
||||
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell
|
||||
from combo.data.management.commands.import_site import Command as ImportSiteCommand
|
||||
from combo.data.management.commands.export_site import Command as ExportSiteCommand
|
||||
from combo.manager.forms import PageVisibilityForm
|
||||
|
@ -192,6 +192,52 @@ def test_import_export_pages_with_links():
|
|||
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
|
||||
|
||||
|
||||
def test_duplicate_page():
|
||||
group1 = Group.objects.create(name='foobar')
|
||||
group2 = Group.objects.create(name='fooblah')
|
||||
|
||||
page = Page.objects.create(
|
||||
title='foo',
|
||||
slug='foo',
|
||||
description="Foo's page")
|
||||
page.groups.set([group1, group2])
|
||||
snapshot = PageSnapshot.objects.create(page=page)
|
||||
page.snapshot = snapshot
|
||||
page.save()
|
||||
|
||||
cell1 = TextCell.objects.create(page=page, text='foo1', order=0, placeholder='content')
|
||||
cell1.groups.set([group1, group2])
|
||||
cell2 = TextCell.objects.create(page=page, text='foo2', order=1, placeholder='content')
|
||||
|
||||
new_page = page.duplicate()
|
||||
assert new_page.pk != page.pk
|
||||
assert new_page.title == 'Copy of foo'
|
||||
assert new_page.slug == page.slug
|
||||
assert new_page.description == page.description
|
||||
assert new_page.parent is None
|
||||
assert new_page.snapshot is None
|
||||
assert list(new_page.groups.all()) == [group1, group2]
|
||||
assert len(new_page.get_cells()) == 2
|
||||
|
||||
new_cell1 = TextCell.objects.get(page=new_page, text='foo1')
|
||||
new_cell2 = TextCell.objects.get(page=new_page, text='foo2')
|
||||
assert new_cell1.pk != cell1.pk
|
||||
assert new_cell1.text == cell1.text
|
||||
assert new_cell1.placeholder == cell1.placeholder
|
||||
assert list(new_cell1.groups.all()) == [group1, group2]
|
||||
assert new_cell2.pk != cell2.pk
|
||||
assert new_cell2.text == cell2.text
|
||||
assert new_cell2.placeholder == cell2.placeholder
|
||||
assert list(new_cell2.groups.all()) == []
|
||||
|
||||
parent = Page.objects.create()
|
||||
page.parent = parent
|
||||
page.save()
|
||||
new_page = page.duplicate()
|
||||
assert new_page.parent == parent
|
||||
|
||||
|
||||
def test_next_previous():
|
||||
Page.objects.all().delete()
|
||||
page = Page()
|
||||
|
|
Loading…
Reference in New Issue