rework delete function to handle cases of multiple snippets

This commit is contained in:
LB 2017-08-23 17:20:01 +02:00 committed by Matt Westcott
parent 316b25e477
commit 4a3590d53b
4 changed files with 138 additions and 19 deletions

View file

@ -1,20 +1,38 @@
{% extends "wagtailadmin/base.html" %}
{% load wagtailadmin_tags i18n %}
{% block titletag %}{% blocktrans with snippet_type_name=model_opts.verbose_name %}Delete {{ snippet_type_name }} - {{ instance }}{% endblocktrans %}{% endblock %}
{% block titletag %}
{% if count == 1 %}
{% blocktrans with snippet_type_name=model_opts.verbose_name %}Delete {{ snippet_type_name }}{% endblocktrans %} - {{ instances|first }}
{% else %}
{{ count }} {{ model_opts.verbose_name_plural|capfirst }}
{% endif %}
{% endblock %}
{% block content %}
{% trans "Delete" as delete_str %}
{% include "wagtailadmin/shared/header.html" with title=delete_str subtitle=instance icon="snippet" %}
{% trans "Delete " as delete_str %}
{% if count == 1 %}
{% include "wagtailadmin/shared/header.html" with title=delete_str subtitle=instances|first icon="snippet" %}
{% else %}
{% include "wagtailadmin/shared/header.html" with title=delete_str subtitle=model_opts.verbose_name_plural|capfirst icon="snippet" %}
{% endif %}
<div class="nice-padding">
{% usage_count_enabled as uc_enabled %}
{% if uc_enabled %}
<div class="usagecount">
<a href="{{ instance.usage_url }}">{% blocktrans count usage_count=instance.get_usage.count %}Used {{ usage_count }} time{% plural %}Used {{ usage_count }} times{% endblocktrans %}</a>
</div>
{% if count == 1 %}
{% usage_count_enabled as uc_enabled %}
{% if uc_enabled %}
<div class="usagecount">
<a href="{{ instances.0.usage_url }}">{% blocktrans count usage_count=instances.0.get_usage.count %}Used {{ usage_count }} time{% plural %}Used {{ usage_count }} times{% endblocktrans %}</a>
</div>
{% endif %}
<p>{% blocktrans with snippet_type_name=model_opts.verbose_name %}Are you sure you want to delete this {{ snippet_type_name }}?{% endblocktrans %}</p>
{% else %}
<p>{% blocktrans with snippet_type_name=model_opts.verbose_name_plural %}Are you sure you want to delete {{ count }} {{ snippet_type_name }}?{% endblocktrans %}</p>
<ul>
{% for instance in instances %}
<li>{{ instance }}</li>
{% endfor %}
</ul>
{% endif %}
<p>{% blocktrans with snippet_type_name=model_opts.verbose_name %}Are you sure you want to delete this {{ snippet_type_name }}?{% endblocktrans %}</p>
<form action="{% url 'wagtailsnippets:delete' model_opts.app_label model_opts.model_name instance.pk|admin_urlquote %}" method="POST">
<form action="{{ submit_url }}" method="POST">
{% csrf_token %}
<input type="submit" value="{% trans 'Yes, delete' %}" class="button serious" />
</form>

View file

@ -366,6 +366,64 @@ class TestSnippetDelete(TestCase, WagtailTestUtils):
self.assertContains(response, self.test_snippet.usage_url())
class TestSnippetDeleteMultipleWithOne(TestCase, WagtailTestUtils):
# test deletion of one snippet using the delete-multiple URL
# behaviour should mimic the TestSnippetDelete but with different URl structure
fixtures = ['test.json']
def setUp(self):
self.snippet = Advert.objects.get(id=1)
self.login()
def test_delete_get(self):
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % (self.snippet.id)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_delete_post(self):
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % (self.snippet.id)
response = self.client.post(url)
# Should be redirected to explorer page
self.assertRedirects(response, reverse('wagtailsnippets:list', args=('tests', 'advert')))
# Check that the page is gone
self.assertEqual(Advert.objects.filter(text='test_advert').count(), 0)
class TestSnippetDeleteMultipleWithThree(TestCase, WagtailTestUtils):
# test deletion of three snippets using the delete-multiple URL
fixtures = ['test.json']
def setUp(self):
# first advert is in the fixtures
Advert.objects.create(text="Boreas").save()
Advert.objects.create(text="Cloud 9").save()
self.snippets = Advert.objects.all()
self.login()
def test_delete_get(self):
# tests that the URL is available on get
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % ('&id='.join(['%s' % snippet.id for snippet in self.snippets]))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_delete_post(self):
# tests that the URL is available on post and deletes snippets
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % ('&id='.join(['%s' % snippet.id for snippet in self.snippets]))
response = self.client.post(url)
# Should be redirected to explorer page
self.assertRedirects(response, reverse('wagtailsnippets:list', args=('tests', 'advert')))
# Check that the page is gone
self.assertEqual(Advert.objects.filter(text='test_advert').count(), 0)
class TestSnippetChooserPanel(TestCase, WagtailTestUtils):
fixtures = ['test.json']
@ -615,6 +673,13 @@ class TestAddOnlyPermissions(TestCase, WagtailTestUtils):
# permission should be denied
self.assertRedirects(response, reverse('wagtailadmin_home'))
def test_get_delete_mulitple(self):
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % self.test_snippet.id
response = self.client.get(url)
# permission should be denied
self.assertRedirects(response, reverse('wagtailadmin_home'))
class TestEditOnlyPermissions(TestCase, WagtailTestUtils):
fixtures = ['test.json']
@ -659,6 +724,13 @@ class TestEditOnlyPermissions(TestCase, WagtailTestUtils):
# permission should be denied
self.assertRedirects(response, reverse('wagtailadmin_home'))
def test_get_delete_mulitple(self):
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % self.test_snippet.id
response = self.client.get(url)
# permission should be denied
self.assertRedirects(response, reverse('wagtailadmin_home'))
class TestDeleteOnlyPermissions(TestCase, WagtailTestUtils):
fixtures = ['test.json']
@ -703,6 +775,13 @@ class TestDeleteOnlyPermissions(TestCase, WagtailTestUtils):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailsnippets/snippets/confirm_delete.html')
def test_get_delete_mulitple(self):
url = reverse('wagtailsnippets:delete-multiple', args=('tests', 'advert'))
url += '?id=%s' % self.test_snippet.id
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailsnippets/snippets/confirm_delete.html')
class TestSnippetEditHandlers(TestCase, WagtailTestUtils):
def test_standard_edit_handler(self):

View file

@ -13,6 +13,7 @@ urlpatterns = [
url(r'^(\w+)/(\w+)/$', snippets.list, name='list'),
url(r'^(\w+)/(\w+)/add/$', snippets.create, name='add'),
url(r'^(\w+)/(\w+)/([^/]+?)/$', snippets.edit, name='edit'),
url(r'^(\w+)/(\w+)/multiple/delete/$', snippets.delete, name='delete-multiple'),
url(r'^(\w+)/(\w+)/([^/]+?)/delete/$', snippets.delete, name='delete'),
url(r'^(\w+)/(\w+)/([^/]+?)/usage/$', snippets.usage, name='usage'),
]

View file

@ -1,3 +1,5 @@
from urllib.parse import urlencode
from django.apps import apps
from django.contrib.admin.utils import quote, unquote
from django.http import Http404
@ -221,29 +223,48 @@ def edit(request, app_label, model_name, pk):
})
def delete(request, app_label, model_name, pk):
def delete(request, app_label, model_name, pk=None):
model = get_snippet_model_from_url_params(app_label, model_name)
permission = get_permission_name('delete', model)
if not request.user.has_perm(permission):
return permission_denied(request)
instance = get_object_or_404(model, pk=unquote(pk))
if pk:
instances = [get_object_or_404(model, pk=unquote(pk))]
else:
ids = request.GET.getlist('id')
instances = model.objects.filter(pk__in=ids)
count = len(instances)
if request.method == 'POST':
instance.delete()
messages.success(
request,
_("{snippet_type} '{instance}' deleted.").format(
for instance in instances:
instance.delete()
if count == 1:
message_content = _("{snippet_type} '{instance}' deleted.").format(
snippet_type=capfirst(model._meta.verbose_name_plural),
instance=instance
)
)
else:
message_content = _("{count} {snippet_type} deleted.").format(
snippet_type=capfirst(model._meta.verbose_name_plural),
count=count
)
messages.success(request, message_content)
return redirect('wagtailsnippets:list', app_label, model_name)
return render(request, 'wagtailsnippets/snippets/confirm_delete.html', {
'model_opts': model._meta,
'instance': instance,
'count': count,
'instances': instances,
'submit_url': (
reverse('wagtailsnippets:delete-multiple', args=(app_label, model_name)) +
'?' + urlencode([('id', instance.pk) for instance in instances])
),
})