wagtailstreamforms 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtailstreamforms/__init__.py +1 -0
- wagtailstreamforms/blocks.py +93 -0
- wagtailstreamforms/conf.py +35 -0
- wagtailstreamforms/fields.py +218 -0
- wagtailstreamforms/forms.py +61 -0
- wagtailstreamforms/hooks.py +62 -0
- wagtailstreamforms/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtailstreamforms/locale/es/LC_MESSAGES/django.po +328 -0
- wagtailstreamforms/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtailstreamforms/locale/nl/LC_MESSAGES/django.po +464 -0
- wagtailstreamforms/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtailstreamforms/locale/tr/LC_MESSAGES/django.po +317 -0
- wagtailstreamforms/management/__init__.py +0 -0
- wagtailstreamforms/management/commands/__init__.py +0 -0
- wagtailstreamforms/management/commands/prunesubmissions.py +29 -0
- wagtailstreamforms/migrations/0001_initial.py +555 -0
- wagtailstreamforms/migrations/0002_form_site.py +21 -0
- wagtailstreamforms/migrations/0003_alter_form_fields.py +20 -0
- wagtailstreamforms/migrations/__init__.py +0 -0
- wagtailstreamforms/models/__init__.py +39 -0
- wagtailstreamforms/models/abstract.py +15 -0
- wagtailstreamforms/models/file.py +35 -0
- wagtailstreamforms/models/form.py +188 -0
- wagtailstreamforms/models/submission.py +27 -0
- wagtailstreamforms/serializers.py +11 -0
- wagtailstreamforms/streamfield.py +48 -0
- wagtailstreamforms/templates/streamforms/advanced_settings.html +25 -0
- wagtailstreamforms/templates/streamforms/confirm_copy.html +26 -0
- wagtailstreamforms/templates/streamforms/confirm_delete.html +23 -0
- wagtailstreamforms/templates/streamforms/form_block.html +10 -0
- wagtailstreamforms/templates/streamforms/index_submissions.html +104 -0
- wagtailstreamforms/templates/streamforms/list_submissions.html +56 -0
- wagtailstreamforms/templates/streamforms/non_existent_form.html +2 -0
- wagtailstreamforms/templates/streamforms/partials/form_field.html +6 -0
- wagtailstreamforms/templates/streamforms/partials/pagination_nav.html +17 -0
- wagtailstreamforms/templates/streamforms/wagtailadmin/shared/datetimepicker_translations.html +39 -0
- wagtailstreamforms/templatetags/__init__.py +0 -0
- wagtailstreamforms/templatetags/streamforms_tags.py +43 -0
- wagtailstreamforms/urls.py +31 -0
- wagtailstreamforms/utils/__init__.py +0 -0
- wagtailstreamforms/utils/apps.py +25 -0
- wagtailstreamforms/utils/general.py +6 -0
- wagtailstreamforms/utils/loading.py +30 -0
- wagtailstreamforms/utils/requests.py +13 -0
- wagtailstreamforms/utils/version.py +0 -0
- wagtailstreamforms/views/__init__.py +4 -0
- wagtailstreamforms/views/advanced_settings.py +51 -0
- wagtailstreamforms/views/copy.py +83 -0
- wagtailstreamforms/views/submission_delete.py +73 -0
- wagtailstreamforms/views/submission_list.py +112 -0
- wagtailstreamforms/wagtail_hooks.py +255 -0
- wagtailstreamforms/wagtailstreamforms_fields.py +274 -0
- wagtailstreamforms/wagtailstreamforms_hooks.py +31 -0
- wagtailstreamforms-0.0.0.dist-info/METADATA +24 -0
- wagtailstreamforms-0.0.0.dist-info/RECORD +58 -0
- wagtailstreamforms-0.0.0.dist-info/WHEEL +5 -0
- wagtailstreamforms-0.0.0.dist-info/licenses/LICENSE +19 -0
- wagtailstreamforms-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from urllib.parse import urlencode
|
|
2
|
+
|
|
3
|
+
from django.template import Library
|
|
4
|
+
from django.utils.safestring import mark_safe
|
|
5
|
+
|
|
6
|
+
from wagtailstreamforms.blocks import WagtailFormBlock
|
|
7
|
+
from wagtailstreamforms.models import Form
|
|
8
|
+
|
|
9
|
+
register = Library()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@register.simple_tag(takes_context=True)
|
|
13
|
+
def url_replace(context, **kwargs):
|
|
14
|
+
"""will append kwargs to the existing url replacing any passed in"""
|
|
15
|
+
|
|
16
|
+
query = context["request"].GET.dict()
|
|
17
|
+
query.update(kwargs)
|
|
18
|
+
return urlencode(query)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@register.simple_tag(takes_context=True)
|
|
22
|
+
def streamforms_form(context, slug, reference, action=".", **kwargs):
|
|
23
|
+
"""
|
|
24
|
+
Renders a form on the page.
|
|
25
|
+
|
|
26
|
+
{% load streamforms_tags %}
|
|
27
|
+
{% streamforms_form "the-form-slug" "some-unique-reference" "." %}
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
form = Form.objects.get(slug=slug)
|
|
32
|
+
|
|
33
|
+
block = WagtailFormBlock()
|
|
34
|
+
|
|
35
|
+
# the context is a RequestContext, we need to turn it into a dict or
|
|
36
|
+
# the blocks in wagtail will start to fail with dict(context)
|
|
37
|
+
return block.render(
|
|
38
|
+
block.to_python({"form": form.pk, "form_action": action, "form_reference": reference}),
|
|
39
|
+
context.flatten(),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
except Form.DoesNotExist:
|
|
43
|
+
return mark_safe("")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
|
|
3
|
+
from wagtailstreamforms import views
|
|
4
|
+
from wagtailstreamforms.utils.loading import get_advanced_settings_model
|
|
5
|
+
|
|
6
|
+
SettingsModel = get_advanced_settings_model()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
urlpatterns = [
|
|
10
|
+
path("<int:pk>/copy/", views.CopyFormView.as_view(), name="streamforms_copy"),
|
|
11
|
+
path(
|
|
12
|
+
"<int:pk>/submissions/",
|
|
13
|
+
views.SubmissionListView.as_view(),
|
|
14
|
+
name="streamforms_submissions",
|
|
15
|
+
),
|
|
16
|
+
path(
|
|
17
|
+
"<int:pk>/submissions/delete/",
|
|
18
|
+
views.SubmissionDeleteView.as_view(),
|
|
19
|
+
name="streamforms_delete_submissions",
|
|
20
|
+
),
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if SettingsModel: # pragma: no cover
|
|
25
|
+
urlpatterns += [
|
|
26
|
+
path(
|
|
27
|
+
"<int:pk>/advanced/",
|
|
28
|
+
views.AdvancedSettingsView.as_view(),
|
|
29
|
+
name="streamforms_advanced",
|
|
30
|
+
)
|
|
31
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from importlib import import_module
|
|
2
|
+
|
|
3
|
+
from django.apps import apps
|
|
4
|
+
from django.utils.module_loading import module_has_submodule
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_app_modules():
|
|
8
|
+
"""
|
|
9
|
+
Generator function that yields a module object for each installed app
|
|
10
|
+
yields tuples of (app_name, module)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
for app in apps.get_app_configs():
|
|
14
|
+
yield app.name, app.module
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_app_submodules(submodule_name):
|
|
18
|
+
"""
|
|
19
|
+
Searches each app module for the specified submodule
|
|
20
|
+
yields tuples of (app_name, module)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
for name, module in get_app_modules():
|
|
24
|
+
if module_has_submodule(module, submodule_name):
|
|
25
|
+
yield name, import_module("%s.%s" % (name, submodule_name))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from django.apps import apps
|
|
2
|
+
from django.core.exceptions import ImproperlyConfigured
|
|
3
|
+
|
|
4
|
+
from wagtailstreamforms.conf import get_setting
|
|
5
|
+
from wagtailstreamforms.models import AbstractFormSetting
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_advanced_settings_model():
|
|
9
|
+
"""
|
|
10
|
+
Returns the advanced form settings model if one is defined
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
model = get_setting("ADVANCED_SETTINGS_MODEL")
|
|
14
|
+
|
|
15
|
+
if not model:
|
|
16
|
+
return
|
|
17
|
+
|
|
18
|
+
def raise_error(msg):
|
|
19
|
+
setting = "WAGTAILSTREAMFORMS_ADVANCED_SETTINGS_MODEL"
|
|
20
|
+
raise ImproperlyConfigured("%s %s" % (setting, msg))
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
model_class = apps.get_model(model, require_ready=False)
|
|
24
|
+
if issubclass(model_class, AbstractFormSetting):
|
|
25
|
+
return model_class
|
|
26
|
+
raise_error("must inherit from 'wagtailstreamforms.models.AbstractFormSetting'")
|
|
27
|
+
except ValueError:
|
|
28
|
+
raise_error("must be of the form 'app_label.model_name'")
|
|
29
|
+
except LookupError:
|
|
30
|
+
raise_error("refers to model '%s' that has not been installed" % model)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from wagtailstreamforms.models import Form
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_form_instance_from_request(request):
|
|
5
|
+
"""Get the form class from the request."""
|
|
6
|
+
|
|
7
|
+
form_id = request.POST.get("form_id")
|
|
8
|
+
if form_id and form_id.isdigit():
|
|
9
|
+
try:
|
|
10
|
+
return Form.objects.get(pk=int(form_id))
|
|
11
|
+
except Form.DoesNotExist:
|
|
12
|
+
pass
|
|
13
|
+
return None
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.contrib import messages
|
|
3
|
+
from django.shortcuts import get_object_or_404
|
|
4
|
+
from django.utils.translation import gettext as _
|
|
5
|
+
from django.views.generic import UpdateView
|
|
6
|
+
|
|
7
|
+
from wagtailstreamforms.models import Form
|
|
8
|
+
from wagtailstreamforms.utils.loading import get_advanced_settings_model
|
|
9
|
+
from wagtailstreamforms.wagtail_hooks import FormURLHelper
|
|
10
|
+
|
|
11
|
+
SettingsModel = get_advanced_settings_model()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AdvancedSettingsForm(forms.ModelForm):
|
|
15
|
+
class Meta:
|
|
16
|
+
exclude = ("form",)
|
|
17
|
+
model = SettingsModel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AdvancedSettingsView(UpdateView):
|
|
21
|
+
form_class = AdvancedSettingsForm
|
|
22
|
+
model = SettingsModel
|
|
23
|
+
template_name = "streamforms/advanced_settings.html"
|
|
24
|
+
success_message = _("Form '%s' advanced settings updated.")
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def url_helper(self):
|
|
28
|
+
return FormURLHelper(model=Form)
|
|
29
|
+
|
|
30
|
+
def get_object(self, queryset=None):
|
|
31
|
+
form_pk = self.kwargs.get("pk")
|
|
32
|
+
form = get_object_or_404(Form, pk=form_pk)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
obj = self.model.objects.get(form=form)
|
|
36
|
+
except self.model.DoesNotExist:
|
|
37
|
+
obj = self.model(form=form)
|
|
38
|
+
|
|
39
|
+
return obj
|
|
40
|
+
|
|
41
|
+
def form_valid(self, form):
|
|
42
|
+
response = super().form_valid(form)
|
|
43
|
+
self.create_success_message()
|
|
44
|
+
return response
|
|
45
|
+
|
|
46
|
+
def create_success_message(self):
|
|
47
|
+
success_message = self.success_message % self.object.form
|
|
48
|
+
messages.success(self.request, success_message)
|
|
49
|
+
|
|
50
|
+
def get_success_url(self):
|
|
51
|
+
return self.url_helper.index_url
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.contrib import messages
|
|
3
|
+
from django.core.exceptions import PermissionDenied
|
|
4
|
+
from django.http import HttpResponseRedirect
|
|
5
|
+
from django.utils.translation import gettext_lazy as _
|
|
6
|
+
from django.views.generic.detail import (
|
|
7
|
+
BaseDetailView,
|
|
8
|
+
SingleObjectTemplateResponseMixin,
|
|
9
|
+
)
|
|
10
|
+
from wagtail_modeladmin.helpers import PermissionHelper
|
|
11
|
+
|
|
12
|
+
from wagtailstreamforms.models import Form
|
|
13
|
+
from wagtailstreamforms.wagtail_hooks import FormURLHelper
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CopyForm(forms.Form):
|
|
17
|
+
title = forms.CharField(label=_("New title"))
|
|
18
|
+
slug = forms.SlugField(label=_("New slug"))
|
|
19
|
+
|
|
20
|
+
def clean_slug(self):
|
|
21
|
+
slug = self.cleaned_data["slug"]
|
|
22
|
+
if Form.objects.filter(slug=slug).exists():
|
|
23
|
+
raise forms.ValidationError("This slug is already in use")
|
|
24
|
+
return slug
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CopyFormView(SingleObjectTemplateResponseMixin, BaseDetailView):
|
|
28
|
+
model = Form
|
|
29
|
+
template_name = "streamforms/confirm_copy.html"
|
|
30
|
+
success_message = _("Form '%s' copied to '%s'.")
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def permission_helper(self):
|
|
34
|
+
return PermissionHelper(model=self.model)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def url_helper(self):
|
|
38
|
+
return FormURLHelper(model=self.model)
|
|
39
|
+
|
|
40
|
+
def dispatch(self, request, *args, **kwargs):
|
|
41
|
+
self.object = self.get_object()
|
|
42
|
+
if not self.permission_helper.user_can_create(self.request.user):
|
|
43
|
+
raise PermissionDenied
|
|
44
|
+
return super().dispatch(request, *args, **kwargs)
|
|
45
|
+
|
|
46
|
+
def get_object(self, queryset=None):
|
|
47
|
+
obj = super().get_object(queryset)
|
|
48
|
+
return obj
|
|
49
|
+
|
|
50
|
+
def copy(self, request, *args, **kwargs):
|
|
51
|
+
form = CopyForm(request.POST)
|
|
52
|
+
|
|
53
|
+
if form.is_valid():
|
|
54
|
+
copied = self.object.copy()
|
|
55
|
+
copied.title = form.cleaned_data["title"]
|
|
56
|
+
copied.slug = form.cleaned_data["slug"]
|
|
57
|
+
|
|
58
|
+
copied.save()
|
|
59
|
+
|
|
60
|
+
self.create_success_message(copied)
|
|
61
|
+
|
|
62
|
+
return HttpResponseRedirect(self.get_success_url())
|
|
63
|
+
|
|
64
|
+
context = self.get_context_data(object=self.object)
|
|
65
|
+
context["form"] = form
|
|
66
|
+
|
|
67
|
+
return self.render_to_response(context)
|
|
68
|
+
|
|
69
|
+
def get(self, request, *args, **kwargs):
|
|
70
|
+
context = self.get_context_data(object=self.object)
|
|
71
|
+
context["form"] = CopyForm(initial={"title": self.object.title, "slug": self.object.slug})
|
|
72
|
+
|
|
73
|
+
return self.render_to_response(context)
|
|
74
|
+
|
|
75
|
+
def post(self, request, *args, **kwargs):
|
|
76
|
+
return self.copy(request, *args, **kwargs)
|
|
77
|
+
|
|
78
|
+
def create_success_message(self, copied):
|
|
79
|
+
success_message = self.success_message % (self.object, copied)
|
|
80
|
+
messages.success(self.request, success_message)
|
|
81
|
+
|
|
82
|
+
def get_success_url(self):
|
|
83
|
+
return self.url_helper.index_url
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from django.contrib import messages
|
|
2
|
+
from django.core.exceptions import PermissionDenied
|
|
3
|
+
from django.http import HttpResponseRedirect
|
|
4
|
+
from django.urls import reverse
|
|
5
|
+
from django.utils.translation import ngettext
|
|
6
|
+
from django.views.generic import DeleteView
|
|
7
|
+
from wagtail_modeladmin.helpers import PermissionHelper
|
|
8
|
+
|
|
9
|
+
from wagtailstreamforms.models import Form
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SubmissionDeleteView(DeleteView):
|
|
13
|
+
model = Form
|
|
14
|
+
template_name = "streamforms/confirm_delete.html"
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def permission_helper(self):
|
|
18
|
+
return PermissionHelper(model=self.model)
|
|
19
|
+
|
|
20
|
+
def dispatch(self, request, *args, **kwargs):
|
|
21
|
+
self.object = self.get_object()
|
|
22
|
+
if not self.permission_helper.user_can_delete_obj(self.request.user, self.object):
|
|
23
|
+
raise PermissionDenied
|
|
24
|
+
return super().dispatch(request, *args, **kwargs)
|
|
25
|
+
|
|
26
|
+
def get_object(self, queryset=None):
|
|
27
|
+
obj = super().get_object(queryset)
|
|
28
|
+
return obj
|
|
29
|
+
|
|
30
|
+
def get_submissions(self):
|
|
31
|
+
submission_ids = self.request.GET.getlist("selected-submissions")
|
|
32
|
+
submission_class = self.object.get_submission_class()
|
|
33
|
+
return submission_class._default_manager.filter(id__in=submission_ids)
|
|
34
|
+
|
|
35
|
+
def get_context_data(self, **kwargs):
|
|
36
|
+
context = super().get_context_data(**kwargs)
|
|
37
|
+
context["submissions"] = self.get_submissions()
|
|
38
|
+
return context
|
|
39
|
+
|
|
40
|
+
def delete(self, request, *args, **kwargs):
|
|
41
|
+
"""
|
|
42
|
+
Django 4.0 uses FormMixin, so this logic has been moved to form_valid.
|
|
43
|
+
|
|
44
|
+
This can be removed once Django 3.2 is no longer supported.
|
|
45
|
+
"""
|
|
46
|
+
success_url = self.get_success_url()
|
|
47
|
+
submissions = self.get_submissions()
|
|
48
|
+
count = submissions.count()
|
|
49
|
+
submissions.delete()
|
|
50
|
+
self.create_success_message(count)
|
|
51
|
+
return HttpResponseRedirect(success_url)
|
|
52
|
+
|
|
53
|
+
def form_valid(self, request, *args, **kwargs):
|
|
54
|
+
success_url = self.get_success_url()
|
|
55
|
+
submissions = self.get_submissions()
|
|
56
|
+
count = submissions.count()
|
|
57
|
+
submissions.delete()
|
|
58
|
+
self.create_success_message(count)
|
|
59
|
+
return HttpResponseRedirect(success_url)
|
|
60
|
+
|
|
61
|
+
def create_success_message(self, count):
|
|
62
|
+
messages.success(
|
|
63
|
+
self.request,
|
|
64
|
+
ngettext(
|
|
65
|
+
"One submission has been deleted.",
|
|
66
|
+
"%(count)d submissions have been deleted.",
|
|
67
|
+
count,
|
|
68
|
+
)
|
|
69
|
+
% {"count": count},
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def get_success_url(self):
|
|
73
|
+
return reverse("wagtailstreamforms:streamforms_submissions", kwargs={"pk": self.object.pk})
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import datetime
|
|
3
|
+
|
|
4
|
+
from django.core.exceptions import PermissionDenied
|
|
5
|
+
from django.http import Http404, HttpResponse
|
|
6
|
+
from django.utils.encoding import smart_str
|
|
7
|
+
from django.utils.translation import gettext as _
|
|
8
|
+
from django.views.generic import ListView
|
|
9
|
+
from django.views.generic.detail import SingleObjectMixin
|
|
10
|
+
from wagtail_modeladmin.helpers import PermissionHelper
|
|
11
|
+
|
|
12
|
+
from wagtailstreamforms import hooks
|
|
13
|
+
from wagtailstreamforms.forms import SelectDateForm
|
|
14
|
+
from wagtailstreamforms.models import Form
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SubmissionListView(SingleObjectMixin, ListView):
|
|
18
|
+
paginate_by = 25
|
|
19
|
+
page_kwarg = "p"
|
|
20
|
+
template_name = "streamforms/index_submissions.html"
|
|
21
|
+
filter_form = None
|
|
22
|
+
model = Form
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def permission_helper(self):
|
|
26
|
+
return PermissionHelper(model=self.model)
|
|
27
|
+
|
|
28
|
+
def dispatch(self, request, *args, **kwargs):
|
|
29
|
+
self.object = self.get_object()
|
|
30
|
+
if not self.permission_helper.user_can_list(self.request.user):
|
|
31
|
+
raise PermissionDenied
|
|
32
|
+
return super().dispatch(request, *args, **kwargs)
|
|
33
|
+
|
|
34
|
+
def get_object(self, queryset=None):
|
|
35
|
+
pk = self.kwargs.get(self.pk_url_kwarg)
|
|
36
|
+
try:
|
|
37
|
+
qs = self.model.objects.all()
|
|
38
|
+
for fn in hooks.get_hooks("construct_form_queryset"):
|
|
39
|
+
qs = fn(qs, self.request)
|
|
40
|
+
return qs.get(pk=pk)
|
|
41
|
+
except self.model.DoesNotExist:
|
|
42
|
+
raise Http404(_("No Form found matching the query"))
|
|
43
|
+
|
|
44
|
+
def get(self, request, *args, **kwargs):
|
|
45
|
+
self.filter_form = SelectDateForm(request.GET)
|
|
46
|
+
|
|
47
|
+
if request.GET.get("action") == "CSV":
|
|
48
|
+
return self.csv()
|
|
49
|
+
|
|
50
|
+
return super().get(request, *args, **kwargs)
|
|
51
|
+
|
|
52
|
+
def csv(self):
|
|
53
|
+
queryset = self.get_queryset()
|
|
54
|
+
data_fields = self.object.get_data_fields()
|
|
55
|
+
data_headings = [smart_str(label) for name, label in data_fields]
|
|
56
|
+
|
|
57
|
+
response = HttpResponse(content_type="text/csv; charset=utf-8")
|
|
58
|
+
response["Content-Disposition"] = "attachment;filename=export.csv"
|
|
59
|
+
|
|
60
|
+
writer = csv.writer(response)
|
|
61
|
+
writer.writerow(data_headings)
|
|
62
|
+
for s in queryset:
|
|
63
|
+
data_row = []
|
|
64
|
+
form_data = s.get_data()
|
|
65
|
+
for name, label in data_fields:
|
|
66
|
+
data_row.append(smart_str(form_data.get(name)))
|
|
67
|
+
writer.writerow(data_row)
|
|
68
|
+
|
|
69
|
+
return response
|
|
70
|
+
|
|
71
|
+
def get_queryset(self):
|
|
72
|
+
submission_class = self.object.get_submission_class()
|
|
73
|
+
self.queryset = submission_class._default_manager.filter(form=self.object)
|
|
74
|
+
|
|
75
|
+
# filter the queryset by the required dates
|
|
76
|
+
if self.filter_form.is_valid():
|
|
77
|
+
date_from = self.filter_form.cleaned_data.get("date_from")
|
|
78
|
+
date_to = self.filter_form.cleaned_data.get("date_to")
|
|
79
|
+
if date_from:
|
|
80
|
+
self.queryset = self.queryset.filter(submit_time__gte=date_from)
|
|
81
|
+
if date_to:
|
|
82
|
+
date_to += datetime.timedelta(days=1)
|
|
83
|
+
self.queryset = self.queryset.filter(submit_time__lte=date_to)
|
|
84
|
+
|
|
85
|
+
return self.queryset.prefetch_related("files")
|
|
86
|
+
|
|
87
|
+
def get_context_data(self, **kwargs):
|
|
88
|
+
context = super().get_context_data(**kwargs)
|
|
89
|
+
|
|
90
|
+
data_fields = self.object.get_data_fields()
|
|
91
|
+
data_headings = [label for name, label in data_fields]
|
|
92
|
+
|
|
93
|
+
# populate data rows from paginator
|
|
94
|
+
data_rows = []
|
|
95
|
+
for s in context["page_obj"]:
|
|
96
|
+
form_data = s.get_data()
|
|
97
|
+
form_files = s.files.all()
|
|
98
|
+
data_row = [form_data.get(name) for name, label in data_fields]
|
|
99
|
+
data_rows.append({"model_id": s.id, "fields": data_row, "files": form_files})
|
|
100
|
+
|
|
101
|
+
context.update(
|
|
102
|
+
{
|
|
103
|
+
"filter_form": self.filter_form,
|
|
104
|
+
"data_rows": data_rows,
|
|
105
|
+
"data_headings": data_headings,
|
|
106
|
+
"has_delete_permission": self.permission_helper.user_can_delete_obj(
|
|
107
|
+
self.request.user, self.object
|
|
108
|
+
),
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return context
|