diff --git a/issue/decorators.py b/issue/decorators.py index 1d69dcf..3685457 100644 --- a/issue/decorators.py +++ b/issue/decorators.py @@ -2,6 +2,8 @@ from functools import wraps from django.contrib.auth.decorators import login_required from django.http import HttpResponseForbidden +from django.shortcuts import render +from django.core.urlresolvers import reverse from issue.models import Project @@ -24,3 +26,30 @@ def project_perm_required(perm): return wrapper return decorator + +def confirmation_required(message, previous=None): + + def decorator(view): + @wraps(view) + def wrapper(request, *args, **kwargs): + if request.GET.get('force'): + return view(request, *args, **kwargs) + prev = previous + if not prev: + prev = request.GET.get('prev') + if not prev: + # improvising + if hasattr(request, 'project'): + prev = reverse('list-issue', + args=[request.project.name]) + else: + prev = reverse('list-project') + c = { + 'message': message, + 'prev': prev, + 'next': request.path + '?force=1', + } + return render(request, 'confirm.html', c) + return wrapper + + return decorator diff --git a/issue/templates/confirm.html b/issue/templates/confirm.html new file mode 100644 index 0000000..71d335f --- /dev/null +++ b/issue/templates/confirm.html @@ -0,0 +1,33 @@ +{% extends 'base.html' %} + +{% load bootstrap_tags %} + +{% block content %} + +
+ +
+

+ Confirmation required +

+
+ +
+
+
+ {{ message }} +
+
+
+ Confirm +
+
+ Cancel +
+
+
+
+ +
+ +{% endblock %} diff --git a/issue/templates/issue/project.html b/issue/templates/issue/project.html index 7e33b86..881946b 100644 --- a/issue/templates/issue/project.html +++ b/issue/templates/issue/project.html @@ -13,7 +13,7 @@
  • Modify this project
  • {% endif %} {% if perm.delete_project %} -
  • Delete this project
  • +
  • Delete this project
  • {% endif %} {% if perm.create_project %}
  • New project…
  • diff --git a/issue/tests.py b/issue/tests.py index 346418b..77d1fe3 100644 --- a/issue/tests.py +++ b/issue/tests.py @@ -266,6 +266,12 @@ class TestProjectsViews(TestCase): expected_url = reverse('list-project') url = reverse('delete-project', args=['project-1']) response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Are you sure') + self.assertQuerysetEqual(Project.objects.all(), + ['project-1', 'project-2'], lambda x: x.name, ordered=False) + url = reverse('delete-project', args=['project-1']) + '?force=1' + response = self.client.get(url) self.assertRedirects(response, expected_url) self.assertQuerysetEqual(Project.objects.all(), ['project-2'], lambda x: x.name, ordered=False) diff --git a/issue/views.py b/issue/views.py index 2d481ff..d50adf0 100644 --- a/issue/views.py +++ b/issue/views.py @@ -6,7 +6,7 @@ from django.http import Http404, HttpResponseForbidden from issue.models import * from issue.forms import * -from issue.decorators import project_perm_required +from issue.decorators import * import shlex @@ -233,6 +233,7 @@ def project_edit(request, project): @project_perm_required('delete_project') +@confirmation_required('Are you sure to delete this project?') def project_delete(request, project): project.delete()