confirm before project deletion
This commit is contained in:
parent
8a0d8a6514
commit
790ddd158b
5 changed files with 71 additions and 2 deletions
|
@ -2,6 +2,8 @@ from functools import wraps
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
from issue.models import Project
|
from issue.models import Project
|
||||||
|
|
||||||
|
@ -24,3 +26,30 @@ def project_perm_required(perm):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
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
|
||||||
|
|
33
issue/templates/confirm.html
Normal file
33
issue/templates/confirm.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% load bootstrap_tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h1>
|
||||||
|
Confirmation required
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="col-md-offset-3 col-md-6">
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="{{ next }}" class="btn btn-primary btn-block">Confirm</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="{{ prev }}" class="btn btn-default btn-block">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -13,7 +13,7 @@
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'edit-project' project.name %}">Modify this project</a></li>
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'edit-project' project.name %}">Modify this project</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perm.delete_project %}
|
{% if perm.delete_project %}
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'delete-project' project.name %}">Delete this project</a></li>
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'delete-project' project.name %}?prev={{ request.get_full_path }}">Delete this project</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perm.create_project %}
|
{% if perm.create_project %}
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'add-project' %}">New project…</a></li>
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'add-project' %}">New project…</a></li>
|
||||||
|
|
|
@ -266,6 +266,12 @@ class TestProjectsViews(TestCase):
|
||||||
expected_url = reverse('list-project')
|
expected_url = reverse('list-project')
|
||||||
url = reverse('delete-project', args=['project-1'])
|
url = reverse('delete-project', args=['project-1'])
|
||||||
response = self.client.get(url)
|
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.assertRedirects(response, expected_url)
|
||||||
self.assertQuerysetEqual(Project.objects.all(),
|
self.assertQuerysetEqual(Project.objects.all(),
|
||||||
['project-2'], lambda x: x.name, ordered=False)
|
['project-2'], lambda x: x.name, ordered=False)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.http import Http404, HttpResponseForbidden
|
||||||
|
|
||||||
from issue.models import *
|
from issue.models import *
|
||||||
from issue.forms import *
|
from issue.forms import *
|
||||||
from issue.decorators import project_perm_required
|
from issue.decorators import *
|
||||||
|
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
|
@ -233,6 +233,7 @@ def project_edit(request, project):
|
||||||
|
|
||||||
|
|
||||||
@project_perm_required('delete_project')
|
@project_perm_required('delete_project')
|
||||||
|
@confirmation_required('Are you sure to delete this project?')
|
||||||
def project_delete(request, project):
|
def project_delete(request, project):
|
||||||
|
|
||||||
project.delete()
|
project.delete()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue