Initial commit
This commit is contained in:
322
env/lib/python3.10/site-packages/wagtail/contrib/forms/views.py
vendored
Normal file
322
env/lib/python3.10/site-packages/wagtail/contrib/forms/views.py
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
import datetime
|
||||
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.urls import reverse
|
||||
from django.utils.translation import gettext, gettext_lazy, ngettext
|
||||
from django.views.generic import TemplateView
|
||||
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.models import Page
|
||||
|
||||
|
||||
def get_submissions_list_view(request, *args, **kwargs):
|
||||
"""Call the form page's list submissions view class"""
|
||||
page_id = kwargs.get("page_id")
|
||||
form_page = get_object_or_404(Page, id=page_id).specific
|
||||
return form_page.serve_submissions_list_view(request, *args, **kwargs)
|
||||
|
||||
|
||||
class ContentTypeColumn(Column):
|
||||
edit_url_name = "wagtailadmin_pages:edit"
|
||||
cell_template_name = "wagtailforms/content_type_column.html"
|
||||
|
||||
def get_url(self, instance):
|
||||
return reverse(self.edit_url_name, args=(quote(instance.pk),))
|
||||
|
||||
def get_cell_context_data(self, instance, parent_context):
|
||||
context = super().get_cell_context_data(instance, parent_context)
|
||||
context["url"] = self.get_url(instance)
|
||||
return context
|
||||
|
||||
|
||||
class FormPagesListView(generic.IndexView):
|
||||
"""Lists the available form pages for the current user"""
|
||||
|
||||
template_name = "wagtailforms/index.html"
|
||||
results_template_name = "wagtailforms/index_results.html"
|
||||
context_object_name = "form_pages"
|
||||
paginate_by = 20
|
||||
page_kwarg = "p"
|
||||
index_url_name = "wagtailforms:index"
|
||||
index_results_url_name = "wagtailforms:index_results"
|
||||
page_title = gettext_lazy("Forms")
|
||||
header_icon = "form"
|
||||
_show_breadcrumbs = True
|
||||
columns = [
|
||||
TitleColumn(
|
||||
"title",
|
||||
classname="title",
|
||||
label=gettext_lazy("Title"),
|
||||
width="50%",
|
||||
url_name="wagtailforms:list_submissions",
|
||||
sort_key="title",
|
||||
),
|
||||
ContentTypeColumn(
|
||||
"content_type",
|
||||
label=gettext_lazy("Origin"),
|
||||
width="50%",
|
||||
sort_key="content_type",
|
||||
),
|
||||
]
|
||||
model = Page
|
||||
is_searchable = False
|
||||
|
||||
def get_breadcrumbs_items(self):
|
||||
return self.breadcrumbs_items + [
|
||||
{"url": "", "label": self.page_title, "sublabel": gettext("Pages")},
|
||||
]
|
||||
|
||||
def get_base_queryset(self):
|
||||
"""Return the queryset of form pages for this view"""
|
||||
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"),
|
||||
field_name="submit_time",
|
||||
widget=DateRangePickerWidget,
|
||||
)
|
||||
|
||||
|
||||
class SubmissionsListView(SpreadsheetExportMixin, BaseListingView):
|
||||
"""Lists submissions for the provided form page"""
|
||||
|
||||
template_name = "wagtailforms/submissions_index.html"
|
||||
results_template_name = "wagtailforms/list_submissions.html"
|
||||
context_object_name = "submissions"
|
||||
form_page = None
|
||||
default_ordering = ("-submit_time",)
|
||||
ordering_csv = ("submit_time",) # keep legacy CSV ordering
|
||||
orderable_fields = (
|
||||
"id",
|
||||
"submit_time",
|
||||
) # used to validate ordering in URL
|
||||
page_title = gettext_lazy("Form data")
|
||||
header_icon = "form"
|
||||
paginate_by = 20
|
||||
filterset_class = SubmissionsListFilterSet
|
||||
forms_index_url_name = "wagtailforms:index"
|
||||
index_url_name = "wagtailforms:list_submissions"
|
||||
index_results_url_name = "wagtailforms:list_submissions_results"
|
||||
_show_breadcrumbs = True
|
||||
show_export_buttons = True
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
"""Check permissions and set the form page"""
|
||||
|
||||
self.form_page = kwargs.get("form_page")
|
||||
|
||||
if not get_forms_for_user(request.user).filter(pk=self.form_page.id).exists():
|
||||
raise PermissionDenied
|
||||
|
||||
if self.is_export:
|
||||
data_fields = self.form_page.get_data_fields()
|
||||
# Set the export fields and the headings for spreadsheet export
|
||||
self.list_export = [field for field, label in data_fields]
|
||||
self.export_headings = dict(data_fields)
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_filterset_kwargs(self):
|
||||
kwargs = super().get_filterset_kwargs()
|
||||
kwargs["queryset"] = self.get_base_queryset()
|
||||
return kwargs
|
||||
|
||||
def get_base_queryset(self):
|
||||
"""Return queryset of form submissions"""
|
||||
submission_class = self.form_page.get_submission_class()
|
||||
queryset = submission_class._default_manager.filter(page=self.form_page)
|
||||
return queryset
|
||||
|
||||
def get_validated_ordering(self):
|
||||
"""Return a dict of field names with ordering labels if ordering is valid"""
|
||||
orderable_fields = self.orderable_fields or ()
|
||||
ordering = {}
|
||||
if self.is_export:
|
||||
# Revert to CSV order_by submit_time ascending for backwards compatibility
|
||||
default_ordering = self.ordering_csv or ()
|
||||
else:
|
||||
default_ordering = self.default_ordering or ()
|
||||
if isinstance(default_ordering, str):
|
||||
default_ordering = (default_ordering,)
|
||||
ordering_strs = self.request.GET.getlist("order_by") or list(default_ordering)
|
||||
for order in ordering_strs:
|
||||
try:
|
||||
_, prefix, field_name = order.rpartition("-")
|
||||
if field_name in orderable_fields:
|
||||
ordering[field_name] = (
|
||||
prefix,
|
||||
"descending" if prefix == "-" else "ascending",
|
||||
)
|
||||
except (IndexError, ValueError):
|
||||
continue # invalid ordering specified, skip it
|
||||
return ordering
|
||||
|
||||
def get_ordering(self):
|
||||
"""Return the field or fields to use for ordering the queryset"""
|
||||
ordering = self.get_validated_ordering()
|
||||
return [values[0] + name for name, values in ordering.items()]
|
||||
|
||||
def get_filename(self):
|
||||
"""Returns the base filename for the generated spreadsheet data file"""
|
||||
return "{}-export-{}".format(
|
||||
self.form_page.slug, datetime.datetime.today().strftime("%Y-%m-%d")
|
||||
)
|
||||
|
||||
def render_to_response(self, context, **response_kwargs):
|
||||
if self.is_export:
|
||||
return self.as_spreadsheet(
|
||||
context["submissions"], self.request.GET.get("export")
|
||||
)
|
||||
return super().render_to_response(context, **response_kwargs)
|
||||
|
||||
def to_row_dict(self, item):
|
||||
"""Orders the submission dictionary for spreadsheet writing"""
|
||||
row_dict = OrderedDict(
|
||||
(field, item.get_data().get(field)) for field in self.list_export
|
||||
)
|
||||
return row_dict
|
||||
|
||||
def get_index_url(self):
|
||||
return reverse(self.index_url_name, args=(self.form_page.id,))
|
||||
|
||||
def get_index_results_url(self):
|
||||
return reverse(self.index_results_url_name, args=(self.form_page.id,))
|
||||
|
||||
def get_page_subtitle(self):
|
||||
return self.form_page.get_admin_display_title()
|
||||
|
||||
def get_breadcrumbs_items(self):
|
||||
return self.breadcrumbs_items + [
|
||||
{
|
||||
"url": reverse(self.forms_index_url_name),
|
||||
"label": gettext("Forms"),
|
||||
},
|
||||
{
|
||||
"url": "",
|
||||
"label": self.get_page_title(),
|
||||
"sublabel": self.get_page_subtitle(),
|
||||
},
|
||||
]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""Return context for view"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
submissions = context[self.context_object_name]
|
||||
data_fields = self.form_page.get_data_fields()
|
||||
data_rows = []
|
||||
context["submissions"] = submissions
|
||||
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,
|
||||
}
|
||||
)
|
||||
|
||||
context.update(
|
||||
{
|
||||
"form_page": self.form_page,
|
||||
"data_headings": data_headings,
|
||||
"data_rows": data_rows,
|
||||
}
|
||||
)
|
||||
|
||||
return context
|
||||
Reference in New Issue
Block a user