0002-page-add-a-duplicate-action-24526.patch
combo/apps/maps/models.py | ||
---|---|---|
319 | 319 |
ctx['group_markers'] = self.group_markers |
320 | 320 |
ctx['marker_behaviour_onclick'] = self.marker_behaviour_onclick |
321 | 321 |
return ctx |
322 | ||
323 |
def duplicate_m2m(self, new_cell): |
|
324 |
# set layers |
|
325 |
new_cell.layers.set(self.layers.all()) |
combo/data/models.py | ||
---|---|---|
434 | 434 |
cells = CellBase.get_cells(page_id=self.id) |
435 | 435 |
return max([self.last_update_timestamp] + [x.last_update_timestamp for x in cells]) |
436 | 436 | |
437 |
def duplicate(self): |
|
438 |
# clone current page |
|
439 |
new_page = copy.deepcopy(self) |
|
440 |
new_page.pk = None |
|
441 |
# set title |
|
442 |
new_page.title = _('Copy of %s') % self.title |
|
443 |
# reset snapshot |
|
444 |
new_page.snapshot = None |
|
445 |
# reset order |
|
446 |
new_page.order = None |
|
447 |
# store new page |
|
448 |
new_page.save() |
|
449 | ||
450 |
# set groups |
|
451 |
new_page.groups.set(self.groups.all()) |
|
452 | ||
453 |
for cell in self.get_cells(): |
|
454 |
cell.duplicate(page_target=new_page) |
|
455 | ||
456 |
return new_page |
|
457 | ||
437 | 458 | |
438 | 459 |
class PageSnapshot(models.Model): |
439 | 460 |
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True) |
... | ... | |
735 | 756 |
def import_subobjects(self, cell_json): |
736 | 757 |
pass |
737 | 758 | |
759 |
def duplicate(self, page_target=None): |
|
760 |
# clone current cell |
|
761 |
new_cell = copy.deepcopy(self) |
|
762 |
new_cell.pk = None |
|
763 |
# set page |
|
764 |
new_cell.page = page_target or self.page |
|
765 |
# store new cell |
|
766 |
new_cell.save() |
|
767 | ||
768 |
# set groups |
|
769 |
new_cell.groups.set(self.groups.all()) |
|
770 | ||
771 |
if hasattr(self, 'duplicate_m2m'): |
|
772 |
self.duplicate_m2m(new_cell) |
|
773 | ||
774 |
return new_cell |
|
775 | ||
776 | ||
738 | 777 |
@register_cell_class |
739 | 778 |
class TextCell(CellBase): |
740 | 779 |
text = RichTextField(_('Text'), blank=True, null=True) |
combo/manager/templates/combo/page_view.html | ||
---|---|---|
11 | 11 |
<ul class="extra-actions-menu"> |
12 | 12 |
<li><a href="{% url 'combo-manager-page-history' pk=object.id %}">{% trans 'history' %}</a></li> |
13 | 13 |
<li><a download href="{% url 'combo-manager-page-export' pk=object.id %}">{% trans 'export' %}</a></li> |
14 |
<li><a href="{% url 'combo-manager-page-duplicate' pk=object.id %}">{% trans 'duplicate' %}</a></li> |
|
14 | 15 |
<li><a rel="popup" href="{% url 'combo-manager-page-delete' pk=object.id %}">{% trans 'delete' %}</a></li> |
15 | 16 |
</ul> |
16 | 17 |
</span> |
combo/manager/urls.py | ||
---|---|---|
53 | 53 |
name='combo-manager-page-delete'), |
54 | 54 |
url(r'^pages/(?P<pk>\w+)/export$', views.page_export, |
55 | 55 |
name='combo-manager-page-export'), |
56 |
url(r'^pages/(?P<pk>\w+)/duplicate$', views.page_duplicate, |
|
57 |
name='combo-manager-page-duplicate'), |
|
56 | 58 |
url(r'^pages/(?P<pk>\w+)/history$', views.page_history, |
57 | 59 |
name='combo-manager-page-history'), |
58 | 60 |
url(r'^pages/(?P<page_pk>\w+)/history/(?P<pk>\w+)/$', views.snapshot_restore, |
combo/manager/views.py | ||
---|---|---|
297 | 297 |
page_export = PageExportView.as_view() |
298 | 298 | |
299 | 299 | |
300 |
class PageDuplicateView(RedirectView): |
|
301 |
permanent = False |
|
302 | ||
303 |
def get_redirect_url(self, pk): |
|
304 |
page = Page.objects.get(pk=pk) |
|
305 |
new_page = page.duplicate() |
|
306 |
messages.info(self.request, _('Page %s has been duplicated.') % page.title) |
|
307 |
return reverse('combo-manager-page-view', kwargs={'pk': new_page.pk}) |
|
308 | ||
309 | ||
310 |
page_duplicate = PageDuplicateView.as_view() |
|
311 | ||
312 | ||
300 | 313 |
class PageHistoryView(ListView): |
301 | 314 |
model = PageSnapshot |
302 | 315 |
template_name = 'combo/page_history.html' |
tests/test_manager.py | ||
---|---|---|
376 | 376 |
resp = resp.form.submit() |
377 | 377 |
assert 'File is not in the expected JSON format.' in resp.text |
378 | 378 | |
379 | ||
380 |
def test_duplicate_page(app, admin_user): |
|
381 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
|
382 |
TextCell.objects.create(page=page, placeholder='content', text='Foobar', order=0) |
|
383 | ||
384 |
app = login(app) |
|
385 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
386 |
resp = resp.click('duplicate') |
|
387 |
new_page = Page.objects.latest('pk') |
|
388 |
assert resp.status_int == 302 |
|
389 |
assert resp.location.endswith('/manage/pages/%s/' % new_page.pk) |
|
390 | ||
391 | ||
379 | 392 |
def test_add_edit_cell(app, admin_user): |
380 | 393 |
Page.objects.all().delete() |
381 | 394 |
page = Page(title='One', slug='one', template_name='standard') |
tests/test_maps_cells.py | ||
---|---|---|
392 | 392 |
features = json.loads(resp.text)['features'] |
393 | 393 |
assert len(features[0]['properties']['display_fields']) == 1 |
394 | 394 |
assert features[0]['properties']['layer']['properties'] == ['id'] |
395 | ||
396 | ||
397 |
def test_duplicate(layer): |
|
398 |
page = Page.objects.create(title='xxx', slug='new', template_name='standard') |
|
399 |
cell = Map.objects.create(page=page, placeholder='content', order=0, public=True, title='Map') |
|
400 |
layer.save() |
|
401 |
cell.layers.add(layer) |
|
402 | ||
403 |
new_cell = cell.duplicate() |
|
404 |
assert list(new_cell.layers.all()) == [layer] |
tests/test_pages.py | ||
---|---|---|
9 | 9 |
from django.test.client import RequestFactory |
10 | 10 |
from django.utils.six import StringIO |
11 | 11 |
from django.utils.timezone import now |
12 |
from combo.data.models import Page, CellBase, TextCell, LinkCell |
|
12 |
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell
|
|
13 | 13 |
from combo.data.management.commands.import_site import Command as ImportSiteCommand |
14 | 14 |
from combo.data.management.commands.export_site import Command as ExportSiteCommand |
15 | 15 | |
... | ... | |
174 | 174 |
assert CellBase.get_cells(page_id=new_page_1.id)[0].link_page_id == new_page_2.id |
175 | 175 |
assert CellBase.get_cells(page_id=new_page_2.id)[0].link_page_id == new_page_1.id |
176 | 176 | |
177 | ||
178 |
def test_duplicate_page(): |
|
179 |
group1 = Group.objects.create(name='foobar') |
|
180 |
group2 = Group.objects.create(name='fooblah') |
|
181 | ||
182 |
page = Page.objects.create( |
|
183 |
title='foo', |
|
184 |
slug='foo', |
|
185 |
description="Foo's page") |
|
186 |
page.groups.set([group1, group2]) |
|
187 |
snapshot = PageSnapshot.objects.create(page=page) |
|
188 |
page.snapshot = snapshot |
|
189 |
page.save() |
|
190 | ||
191 |
cell1 = TextCell.objects.create(page=page, text='foo1', order=0, placeholder='content') |
|
192 |
cell1.groups.set([group1, group2]) |
|
193 |
cell2 = TextCell.objects.create(page=page, text='foo2', order=1, placeholder='content') |
|
194 | ||
195 |
new_page = page.duplicate() |
|
196 |
assert new_page.pk != page.pk |
|
197 |
assert new_page.title == 'Copy of foo' |
|
198 |
assert new_page.slug == page.slug |
|
199 |
assert new_page.description == page.description |
|
200 |
assert new_page.parent is None |
|
201 |
assert new_page.snapshot is None |
|
202 |
assert list(new_page.groups.all()) == [group1, group2] |
|
203 |
assert len(new_page.get_cells()) == 2 |
|
204 | ||
205 |
new_cell1 = TextCell.objects.get(page=new_page, text='foo1') |
|
206 |
new_cell2 = TextCell.objects.get(page=new_page, text='foo2') |
|
207 |
assert new_cell1.pk != cell1.pk |
|
208 |
assert new_cell1.text == cell1.text |
|
209 |
assert new_cell1.placeholder == cell1.placeholder |
|
210 |
assert list(new_cell1.groups.all()) == [group1, group2] |
|
211 |
assert new_cell2.pk != cell2.pk |
|
212 |
assert new_cell2.text == cell2.text |
|
213 |
assert new_cell2.placeholder == cell2.placeholder |
|
214 |
assert list(new_cell2.groups.all()) == [] |
|
215 | ||
216 |
parent = Page.objects.create() |
|
217 |
page.parent = parent |
|
218 |
page.save() |
|
219 |
new_page = page.duplicate() |
|
220 |
assert new_page.parent == parent |
|
221 | ||
222 | ||
177 | 223 |
def test_next_previous(): |
178 | 224 |
Page.objects.all().delete() |
179 | 225 |
page = Page() |
180 |
- |