kopia lustrzana https://github.com/wagtail/wagtail
Merge ce967a404a
into 7c6187f06c
commit
4efca19d74
|
@ -0,0 +1,31 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ngettext
|
||||
|
||||
from wagtail.contrib.forms.bulk_actions.form_bulk_action import FormSubmissionBulkAction
|
||||
from wagtail.contrib.forms.utils import get_forms_for_user
|
||||
|
||||
|
||||
class DeleteBulkAction(FormSubmissionBulkAction):
|
||||
display_name = _("Delete")
|
||||
aria_label = _("Delete selected objects")
|
||||
action_type = "delete"
|
||||
template_name = "bulk_actions/confirm_bulk_delete.html"
|
||||
|
||||
def check_perm(self, obj):
|
||||
return get_forms_for_user(self.request.user).exists()
|
||||
|
||||
@classmethod
|
||||
def execute_action(cls, objects, **kwargs):
|
||||
num_forms = 0
|
||||
for obj in objects:
|
||||
num_forms = num_forms + 1
|
||||
obj.delete()
|
||||
return num_forms, 0
|
||||
|
||||
def get_success_message(self, count, num_child_objects):
|
||||
|
||||
return ngettext(
|
||||
"One submission has been deleted.",
|
||||
"%(count)d submissions have been deleted.",
|
||||
count,
|
||||
) % {"count": count}
|
|
@ -0,0 +1,10 @@
|
|||
from wagtail.admin.views.bulk_action import BulkAction
|
||||
from wagtail.contrib.forms.models import FormSubmission
|
||||
|
||||
|
||||
class FormSubmissionBulkAction(BulkAction):
|
||||
models = [FormSubmission]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
return context
|
|
@ -0,0 +1,41 @@
|
|||
{% extends 'wagtailadmin/bulk_actions/confirmation/base.html' %}
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
|
||||
{% block titletag %}{% blocktrans count counter=items|length %}Delete 1 item{% plural %}Delete {{ counter }} items{% endblocktrans %}{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Delete" as del_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=del_str icon="doc-empty-inverse" %}
|
||||
{% endblock header %}
|
||||
|
||||
|
||||
{% block items_with_access %}
|
||||
{% if items %}
|
||||
<p>
|
||||
{% blocktrans trimmed count counter=items|length %}
|
||||
Are you sure you want to delete this form submission?
|
||||
{% plural %}
|
||||
Are you sure you want to delete these form submissions?
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
{% include 'bulk_actions/list_form_submissions.html' %}
|
||||
{% endif %}
|
||||
{% endblock items_with_access %}
|
||||
|
||||
{% block items_with_no_access %}
|
||||
|
||||
{% blocktranslate trimmed asvar no_access_msg count counter=items_with_no_access|length %}You don't have permission to delete this item{% plural %}You don't have permission to delete these items{% endblocktranslate %}
|
||||
{% include 'bulk_actions/list_items_with_no_access.html' with items=items_with_no_access %}
|
||||
|
||||
{% endblock items_with_no_access %}
|
||||
|
||||
{% block form_section %}
|
||||
{% if items %}
|
||||
{% trans 'Yes, delete' as action_button_text %}
|
||||
{% trans "No, don't delete" as no_action_button_text %}
|
||||
{% include 'wagtailadmin/bulk_actions/confirmation/form.html' with action_button_class="serious" %}
|
||||
{% else %}
|
||||
{% include 'wagtailadmin/bulk_actions/confirmation/go_back.html' %}
|
||||
{% endif %}
|
||||
{% endblock form_section %}
|
|
@ -0,0 +1,29 @@
|
|||
{% load i18n %}
|
||||
<table class="listing">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="submit_time" class="">
|
||||
Submission date
|
||||
</th>
|
||||
{% for heading in data_headings %}
|
||||
<th>
|
||||
{{ heading.name }}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% for item in items %}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{{item.item.submit_time}}
|
||||
</td>
|
||||
{% for label,data in item.item.form_data.items %}
|
||||
<td>
|
||||
{{ data }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
{% endfor %}
|
||||
</table>
|
|
@ -0,0 +1,6 @@
|
|||
{% extends 'wagtailadmin/bulk_actions/confirmation/list_items_with_no_access.html' %}
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
|
||||
{% block per_item %}
|
||||
{{ item }}
|
||||
{% endblock per_item %}
|
|
@ -1,23 +0,0 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titletag %}{% blocktrans trimmed with title=page.title %}Delete form data {{ title }}{% endblocktrans %}{% endblock %}
|
||||
{% block bodyclass %}menu-explorer{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% trans "Delete form data" as del_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=del_str subtitle=page.title icon="doc-empty-inverse" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<p>
|
||||
{% blocktrans trimmed count counter=submissions.count %}
|
||||
Are you sure you want to delete this form submission?
|
||||
{% plural %}
|
||||
Are you sure you want to delete these form submissions?
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<form action="{% url 'wagtailforms:delete_submissions' page.id %}?{{ request.GET.urlencode }}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Delete' %}" class="button serious">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,14 +1,14 @@
|
|||
{% extends "wagtailadmin/generic/index_results.html" %}
|
||||
{% load i18n %}
|
||||
{% load i18n l10n wagtailadmin_tags %}
|
||||
{% block results %}
|
||||
<form class="w-overflow-auto" data-controller="w-bulk" data-w-bulk-action-inactive-class="w-invisible" action="{% url 'wagtailforms:delete_submissions' form_page.id %}" method="get">
|
||||
<form class="w-overflow-auto" data-controller="w-bulk" data-w-bulk-action-inactive-class="w-invisible">
|
||||
<table class="listing">
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" data-action="w-bulk#toggleAll" data-w-bulk-target="all" /></th>
|
||||
{% include 'wagtailadmin/bulk_actions/select_all_checkbox_cell.html' %}
|
||||
{% for heading in data_headings %}
|
||||
<th id="{{ heading.name }}" class="{% if heading.order %}ordered icon {% if heading.order == 'ascending' %}icon-arrow-up-after{% else %}icon-arrow-down-after{% endif %}{% endif %}">
|
||||
{% if heading.order %}<a href="?order_by={% if heading.order == 'ascending' %}-{% endif %}{{ heading.name }}">{{ heading.label }}</a>{% else %}{{ heading.label }}{% endif %}
|
||||
|
@ -17,10 +17,16 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% trans "Select response" as checkbox_aria_label %}
|
||||
{% for row in data_rows %}
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" name="selected-submissions" class="select-submission" value="{{ row.model_id }}" data-action="w-bulk#toggle" data-w-bulk-target="item" />
|
||||
<td class="bulk-action-checkbox-cell">
|
||||
<input type="checkbox"
|
||||
{% if obj_type == 'data_rows' %}data-page-status="{% if instance.live %}live{% else %}draft{% endif %}"{% endif %}
|
||||
data-object-id="{{ row.id|unlocalize|admin_urlquote }}" data-bulk-action-checkbox class="bulk-action-checkbox"
|
||||
aria-label="{% trans "Select" %}"
|
||||
{% if aria_describedby %}aria-describedby="{{ aria_describedby }}"{% endif %}
|
||||
/>
|
||||
</td>
|
||||
{% for cell in row.fields %}
|
||||
<td>
|
||||
|
@ -31,11 +37,6 @@
|
|||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="nice-padding">
|
||||
<button class="button no w-invisible" data-w-bulk-target="action">
|
||||
{% trans "Delete selected submissions" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
{% extends "wagtailadmin/generic/listing.html" %}
|
||||
{% load i18n %}
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
{% block titletag %}{% blocktrans trimmed with form_title=form_page.title|capfirst %}Submissions of {{ form_title }}{% endblocktrans %}{% endblock %}
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
window.wagtailConfig.BULK_ACTION_ITEM_TYPE = 'SNIPPET';
|
||||
</script>
|
||||
<script defer src="{% versioned_static 'wagtailadmin/js/bulk-actions.js' %}"></script>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block bulk_actions %}
|
||||
{% trans "Select all documents in listing" as select_all_text %}
|
||||
{% include 'wagtailadmin/bulk_actions/footer.html' with select_all_obj_text=select_all_text app_label=app_label model_name=model_name objects=data_rows %}
|
||||
{% endblock %}
|
|
@ -1201,63 +1201,84 @@ class TestDeleteFormSubmission(WagtailTestUtils, TestCase):
|
|||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.form_model = FormSubmission
|
||||
self.login(username="siteeditor", password="password")
|
||||
self.form_page = Page.objects.get(url_path="/home/contact-us/")
|
||||
|
||||
def test_delete_submission_show_confirmation(self):
|
||||
response = self.client.get(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ f"?selected-submissions={FormSubmission.objects.first().id}"
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ f"?&id={FormSubmission.objects.first().id}"
|
||||
)
|
||||
# Check show confirm page when HTTP method is GET
|
||||
self.assertTemplateUsed(response, "wagtailforms/confirm_delete.html")
|
||||
self.assertTemplateUsed(response, "bulk_actions/confirm_bulk_delete.html")
|
||||
|
||||
# Check that the deletion has not happened with GET request
|
||||
self.assertEqual(FormSubmission.objects.count(), 2)
|
||||
|
||||
def test_delete_submission_with_permissions(self):
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ f"?selected-submissions={FormSubmission.objects.first().id}"
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ f"?&id={FormSubmission.objects.first().id}"
|
||||
)
|
||||
|
||||
# Check that the submission is gone
|
||||
self.assertEqual(FormSubmission.objects.count(), 1)
|
||||
# Should be redirected to list of submissions
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse("wagtailforms:list_submissions", args=(self.form_page.id,)),
|
||||
)
|
||||
|
||||
def test_delete_multiple_submissions_with_permissions(self):
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}&selected-submissions={}".format(
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ "?&id={}&id={}".format(
|
||||
FormSubmission.objects.first().id, FormSubmission.objects.last().id
|
||||
)
|
||||
)
|
||||
|
||||
# Check that both submissions are gone
|
||||
self.assertEqual(FormSubmission.objects.count(), 0)
|
||||
# Should be redirected to list of submissions
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse("wagtailforms:list_submissions", args=(self.form_page.id,)),
|
||||
)
|
||||
|
||||
def test_delete_submission_bad_permissions(self):
|
||||
self.login(username="eventeditor", password="password")
|
||||
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ f"?selected-submissions={FormSubmission.objects.first().id}"
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ f"?&id={FormSubmission.objects.first().id}"
|
||||
)
|
||||
|
||||
# Check that the user received a permission denied response
|
||||
self.assertRedirects(response, "/admin/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Check that the deletion has not happened
|
||||
self.assertEqual(FormSubmission.objects.count(), 2)
|
||||
html = response.content.decode()
|
||||
self.assertInHTML(
|
||||
f"<p>You don't have permission to delete this item</p>",
|
||||
html,
|
||||
)
|
||||
|
||||
def test_delete_submission_after_filter_form_submissions_for_user_hook(self):
|
||||
# Hook forbids to delete form submissions for everyone
|
||||
|
@ -1267,26 +1288,24 @@ class TestDeleteFormSubmission(WagtailTestUtils, TestCase):
|
|||
with self.register_hook(
|
||||
"filter_form_submissions_for_user", construct_forms_for_user
|
||||
):
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ f"?selected-submissions={FormSubmission.objects.first().id}"
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ f"?&id={FormSubmission.objects.first().id}"
|
||||
)
|
||||
|
||||
# An user can't delete a from submission with the hook
|
||||
self.assertRedirects(response, "/admin/")
|
||||
self.assertEqual(FormSubmission.objects.count(), 2)
|
||||
|
||||
# An user can delete a form submission without the hook
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}".format(
|
||||
CustomFormPageSubmission.objects.first().id
|
||||
)
|
||||
)
|
||||
self.assertEqual(FormSubmission.objects.count(), 1)
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse("wagtailforms:list_submissions", args=(self.form_page.id,)),
|
||||
self.assertEqual(response.status_code, 200)
|
||||
html = response.content.decode()
|
||||
self.assertInHTML(
|
||||
f"<p>You don't have permission to delete this item</p>",
|
||||
html,
|
||||
)
|
||||
|
||||
|
||||
|
@ -1294,43 +1313,56 @@ class TestDeleteCustomFormSubmission(WagtailTestUtils, TestCase):
|
|||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.form_model = CustomFormPageSubmission
|
||||
self.login(username="siteeditor", password="password")
|
||||
self.form_page = Page.objects.get(url_path="/home/contact-us-one-more-time/")
|
||||
|
||||
def test_delete_submission_show_confirmation(self):
|
||||
response = self.client.get(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}".format(
|
||||
CustomFormPageSubmission.objects.first().id
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ "?&id={}".format(CustomFormPageSubmission.objects.first().id)
|
||||
)
|
||||
|
||||
# Check show confirm page when HTTP method is GET
|
||||
self.assertTemplateUsed(response, "wagtailforms/confirm_delete.html")
|
||||
self.assertTemplateUsed(response, "bulk_actions/confirm_bulk_delete.html")
|
||||
|
||||
# Check that the deletion has not happened with GET request
|
||||
self.assertEqual(CustomFormPageSubmission.objects.count(), 2)
|
||||
|
||||
def test_delete_submission_with_permissions(self):
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}".format(
|
||||
CustomFormPageSubmission.objects.first().id
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ "?&id={}".format(CustomFormPageSubmission.objects.first().id)
|
||||
)
|
||||
|
||||
# Check that the submission is gone
|
||||
self.assertEqual(CustomFormPageSubmission.objects.count(), 1)
|
||||
# Should be redirected to list of submissions
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse("wagtailforms:list_submissions", args=(self.form_page.id,)),
|
||||
)
|
||||
|
||||
def test_delete_multiple_submissions_with_permissions(self):
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}&selected-submissions={}".format(
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ "?&id={}&id={}".format(
|
||||
CustomFormPageSubmission.objects.first().id,
|
||||
CustomFormPageSubmission.objects.last().id,
|
||||
)
|
||||
|
@ -1338,27 +1370,28 @@ class TestDeleteCustomFormSubmission(WagtailTestUtils, TestCase):
|
|||
|
||||
# Check that both submissions are gone
|
||||
self.assertEqual(CustomFormPageSubmission.objects.count(), 0)
|
||||
# Should be redirected to list of submissions
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse("wagtailforms:list_submissions", args=(self.form_page.id,)),
|
||||
)
|
||||
|
||||
def test_delete_submission_bad_permissions(self):
|
||||
self.login(username="eventeditor", password="password")
|
||||
|
||||
response = self.client.post(
|
||||
reverse("wagtailforms:delete_submissions", args=(self.form_page.id,))
|
||||
+ "?selected-submissions={}".format(
|
||||
CustomFormPageSubmission.objects.first().id
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wagtail_bulk_action",
|
||||
args=(
|
||||
self.form_model._meta.app_label,
|
||||
self.form_model._meta.model_name,
|
||||
"delete",
|
||||
),
|
||||
)
|
||||
+ "?&id={}".format(CustomFormPageSubmission.objects.first().id)
|
||||
)
|
||||
|
||||
# Check that the user received a permission denied response
|
||||
self.assertRedirects(response, "/admin/")
|
||||
|
||||
# Check that the deletion has not happened
|
||||
self.assertEqual(CustomFormPageSubmission.objects.count(), 2)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
html = response.content.decode()
|
||||
self.assertInHTML(
|
||||
f"<p>You don't have permission to delete this item</p>",
|
||||
html,
|
||||
)
|
||||
|
||||
|
||||
class TestFormsWithCustomSubmissionsList(WagtailTestUtils, TestCase):
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from django.urls import path
|
||||
|
||||
from wagtail.contrib.forms.views import (
|
||||
DeleteSubmissionsView,
|
||||
FormPagesListView,
|
||||
get_submissions_list_view,
|
||||
)
|
||||
|
@ -21,9 +20,4 @@ urlpatterns = [
|
|||
{"results_only": True},
|
||||
name="list_submissions_results",
|
||||
),
|
||||
path(
|
||||
"submissions/<int:page_id>/delete/",
|
||||
DeleteSubmissionsView.as_view(),
|
||||
name="delete_submissions",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -45,3 +45,44 @@ def get_forms_for_user(user):
|
|||
editable_forms = fn(user, editable_forms)
|
||||
|
||||
return editable_forms
|
||||
|
||||
def get_form_submissions_as_data(
|
||||
data_fields={}, submissions=[], orderable_fields=[], ordering_by_field={}
|
||||
):
|
||||
"""
|
||||
Build data_rows as list of dicts containing id and fields and
|
||||
build data_headings as list of dicts containing id and fields
|
||||
"""
|
||||
|
||||
data_rows = []
|
||||
for submission in submissions:
|
||||
form_data = submission.get_data()
|
||||
data_row = []
|
||||
for name, label in data_fields:
|
||||
val = form_data.get(name)
|
||||
if isinstance(val, list):
|
||||
val = ", ".join(val)
|
||||
data_row.append(val)
|
||||
data_rows.append({"id": submission.id, "fields": data_row})
|
||||
|
||||
data_headings = []
|
||||
for name, label in data_fields:
|
||||
order_label = None
|
||||
if name in orderable_fields:
|
||||
order = ordering_by_field.get(name)
|
||||
if order:
|
||||
order_label = order[1] # 'ascending' or 'descending'
|
||||
else:
|
||||
order_label = "orderable" # not ordered yet but can be
|
||||
data_headings.append(
|
||||
{
|
||||
"name": name,
|
||||
"label": label,
|
||||
"order": order_label,
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
data_headings,
|
||||
data_rows,
|
||||
)
|
|
@ -3,19 +3,17 @@ from collections import OrderedDict
|
|||
|
||||
from django.contrib.admin.utils import quote
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext, gettext_lazy, ngettext
|
||||
from django.views.generic import TemplateView
|
||||
from django.utils.translation import gettext, gettext_lazy
|
||||
from django_filters import DateFromToRangeFilter
|
||||
|
||||
from wagtail.admin import messages
|
||||
from wagtail.admin.filters import DateRangePickerWidget, WagtailFilterSet
|
||||
from wagtail.admin.ui.tables import Column, TitleColumn
|
||||
from wagtail.admin.views import generic
|
||||
from wagtail.admin.views.generic.base import BaseListingView
|
||||
from wagtail.admin.views.mixins import SpreadsheetExportMixin
|
||||
from wagtail.contrib.forms.utils import get_forms_for_user
|
||||
from wagtail.contrib.forms.utils import get_form_submissions_as_data, get_forms_for_user
|
||||
from wagtail.models import Page
|
||||
|
||||
|
||||
|
@ -81,69 +79,6 @@ class FormPagesListView(generic.IndexView):
|
|||
return get_forms_for_user(self.request.user).select_related("content_type")
|
||||
|
||||
|
||||
class DeleteSubmissionsView(TemplateView):
|
||||
"""Delete the selected submissions"""
|
||||
|
||||
template_name = "wagtailforms/confirm_delete.html"
|
||||
page = None
|
||||
submissions = None
|
||||
success_url = "wagtailforms:list_submissions"
|
||||
|
||||
def get_queryset(self):
|
||||
"""Returns a queryset for the selected submissions"""
|
||||
submission_ids = self.request.GET.getlist("selected-submissions")
|
||||
submission_class = self.page.get_submission_class()
|
||||
return submission_class._default_manager.filter(id__in=submission_ids)
|
||||
|
||||
def handle_delete(self, submissions):
|
||||
"""Deletes the given queryset"""
|
||||
count = submissions.count()
|
||||
submissions.delete()
|
||||
messages.success(
|
||||
self.request,
|
||||
ngettext(
|
||||
"One submission has been deleted.",
|
||||
"%(count)d submissions have been deleted.",
|
||||
count,
|
||||
)
|
||||
% {"count": count},
|
||||
)
|
||||
|
||||
def get_success_url(self):
|
||||
"""Returns the success URL to redirect to after a successful deletion"""
|
||||
return self.success_url
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
"""Check permissions, set the page and submissions, handle delete"""
|
||||
page_id = kwargs.get("page_id")
|
||||
|
||||
if not get_forms_for_user(self.request.user).filter(id=page_id).exists():
|
||||
raise PermissionDenied
|
||||
|
||||
self.page = get_object_or_404(Page, id=page_id).specific
|
||||
|
||||
self.submissions = self.get_queryset()
|
||||
|
||||
if self.request.method == "POST":
|
||||
self.handle_delete(self.submissions)
|
||||
return redirect(self.get_success_url(), page_id)
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""Get the context for this view"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context.update(
|
||||
{
|
||||
"page": self.page,
|
||||
"submissions": self.submissions,
|
||||
}
|
||||
)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class SubmissionsListFilterSet(WagtailFilterSet):
|
||||
date = DateFromToRangeFilter(
|
||||
label=gettext_lazy("Submission date"),
|
||||
|
@ -280,43 +215,22 @@ class SubmissionsListView(SpreadsheetExportMixin, BaseListingView):
|
|||
data_fields = self.form_page.get_data_fields()
|
||||
data_rows = []
|
||||
context["submissions"] = submissions
|
||||
context["page_title"] = self.page_title
|
||||
if not self.is_export:
|
||||
# Build data_rows as list of dicts containing model_id and fields
|
||||
for submission in submissions:
|
||||
form_data = submission.get_data()
|
||||
data_row = []
|
||||
for name, label in data_fields:
|
||||
val = form_data.get(name)
|
||||
if isinstance(val, list):
|
||||
val = ", ".join(val)
|
||||
data_row.append(val)
|
||||
data_rows.append({"model_id": submission.id, "fields": data_row})
|
||||
# Build data_headings as list of dicts containing model_id and fields
|
||||
ordering_by_field = self.get_validated_ordering()
|
||||
orderable_fields = self.orderable_fields
|
||||
data_headings = []
|
||||
for name, label in data_fields:
|
||||
order_label = None
|
||||
if name in orderable_fields:
|
||||
order = ordering_by_field.get(name)
|
||||
if order:
|
||||
order_label = order[1] # 'ascending' or 'descending'
|
||||
else:
|
||||
order_label = "orderable" # not ordered yet but can be
|
||||
data_headings.append(
|
||||
{
|
||||
"name": name,
|
||||
"label": label,
|
||||
"order": order_label,
|
||||
}
|
||||
)
|
||||
(data_headings, data_rows) = get_form_submissions_as_data(
|
||||
data_fields=data_fields,
|
||||
submissions=submissions,
|
||||
orderable_fields=self.orderable_fields,
|
||||
ordering_by_field=self.get_validated_ordering(),
|
||||
)
|
||||
|
||||
context.update(
|
||||
{
|
||||
"app_label": "wagtailforms",
|
||||
"model_name": "formsubmission",
|
||||
"form_page": self.form_page,
|
||||
"data_headings": data_headings,
|
||||
"data_rows": data_rows,
|
||||
}
|
||||
)
|
||||
|
||||
return context
|
||||
return context
|
|
@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from wagtail import hooks
|
||||
from wagtail.admin.menu import MenuItem
|
||||
from wagtail.contrib.forms import urls
|
||||
from wagtail.contrib.forms.bulk_actions.delete import DeleteBulkAction
|
||||
from wagtail.contrib.forms.utils import get_forms_for_user
|
||||
|
||||
|
||||
|
@ -29,3 +30,7 @@ def register_forms_menu_item():
|
|||
icon_name="form",
|
||||
order=700,
|
||||
)
|
||||
|
||||
|
||||
for action_class in [DeleteBulkAction]:
|
||||
hooks.register("register_bulk_action", action_class)
|
||||
|
|
Ładowanie…
Reference in New Issue