Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/import_export/mixins.py: 35%
110 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import warnings
3from django.conf import settings
4from django.http import HttpResponse
5from django.utils.timezone import now
6from django.views.generic.edit import FormView
8from .formats import base_formats
9from .forms import ExportForm
10from .resources import modelresource_factory
11from .signals import post_export
14class BaseImportExportMixin:
15 formats = base_formats.DEFAULT_FORMATS
16 resource_class = None
17 resource_classes = []
19 def check_resource_classes(self, resource_classes):
20 if resource_classes and not hasattr(resource_classes, '__getitem__'):
21 raise Exception("The resource_classes field type must be subscriptable (list, tuple, ...)")
23 def get_resource_classes(self):
24 """ Return subscriptable type (list, tuple, ...) containing resource classes """
25 if self.resource_classes and self.resource_class:
26 raise Exception("Only one of 'resource_class' and 'resource_classes' can be set")
27 if hasattr(self, 'get_resource_class'):
28 warnings.warn(
29 "The 'get_resource_class()' method has been deprecated. "
30 "Please implement the new 'get_resource_classes()' method",
31 DeprecationWarning,
32 )
33 return [self.get_resource_class()]
34 if self.resource_class:
35 warnings.warn(
36 "The 'resource_class' field has been deprecated. "
37 "Please implement the new 'resource_classes' field",
38 DeprecationWarning,
39 )
40 if not self.resource_classes and not self.resource_class:
41 return [modelresource_factory(self.model)]
42 if self.resource_classes:
43 return self.resource_classes
44 return [self.resource_class]
46 def get_resource_kwargs(self, request, *args, **kwargs):
47 return {}
49 def get_resource_index(self, form):
50 resource_index = 0
51 if form and 'resource' in form.cleaned_data:
52 try:
53 resource_index = int(form.cleaned_data['resource'])
54 except ValueError:
55 pass
56 return resource_index
59class BaseImportMixin(BaseImportExportMixin):
61 def get_import_resource_classes(self):
62 """
63 Returns ResourceClass subscriptable (list, tuple, ...) to use for import.
64 """
65 if hasattr(self, 'get_import_resource_class'):
66 warnings.warn(
67 "The 'get_import_resource_class()' method has been deprecated. "
68 "Please implement the new 'get_import_resource_classes()' method",
69 DeprecationWarning,
70 )
71 return [self.get_import_resource_class()]
73 resource_classes = self.get_resource_classes()
74 self.check_resource_classes(resource_classes)
75 return resource_classes
77 def get_import_formats(self):
78 """
79 Returns available import formats.
80 """
81 return [f for f in self.formats if f().can_import()]
83 def get_import_resource_kwargs(self, request, *args, **kwargs):
84 return self.get_resource_kwargs(request, *args, **kwargs)
86 def choose_import_resource_class(self, form):
87 resource_index = self.get_resource_index(form)
88 return self.get_import_resource_classes()[resource_index]
91class BaseExportMixin(BaseImportExportMixin):
92 model = None
93 escape_exported_data = False
95 @property
96 def should_escape_output(self):
97 return getattr(settings, 'IMPORT_EXPORT_ESCAPE_OUTPUT_ON_EXPORT', self.escape_exported_data)
99 def get_export_formats(self):
100 """
101 Returns available export formats.
102 """
103 return [f for f in self.formats if f().can_export()]
105 def get_export_resource_classes(self):
106 """
107 Returns ResourceClass subscriptable (list, tuple, ...) to use for export.
108 """
109 if hasattr(self, 'get_export_resource_class'):
110 warnings.warn(
111 "The 'get_export_resource_class()' method has been deprecated. "
112 "Please implement the new 'get_export_resource_classes()' method",
113 DeprecationWarning,
114 )
115 return [self.get_export_resource_class()]
117 resource_classes = self.get_resource_classes()
118 self.check_resource_classes(resource_classes)
119 return resource_classes
121 def choose_export_resource_class(self, form):
122 resource_index = self.get_resource_index(form)
123 return self.get_export_resource_classes()[resource_index]
125 def get_export_resource_kwargs(self, request, *args, **kwargs):
126 return self.get_resource_kwargs(request, *args, **kwargs)
128 def get_data_for_export(self, request, queryset, *args, **kwargs):
129 export_form = kwargs.pop('export_form', None)
130 return self.choose_export_resource_class(export_form)\
131 (**self.get_export_resource_kwargs(request, *args, **kwargs))\
132 .export(queryset, *args, **kwargs)
134 def get_export_filename(self, file_format):
135 date_str = now().strftime('%Y-%m-%d')
136 filename = "%s-%s.%s" % (self.model.__name__,
137 date_str,
138 file_format.get_extension())
139 return filename
142class ExportViewMixin(BaseExportMixin):
143 form_class = ExportForm
145 def get_export_data(self, file_format, queryset, *args, **kwargs):
146 """
147 Returns file_format representation for given queryset.
148 """
149 data = self.get_data_for_export(self.request, queryset, *args, **kwargs)
150 export_data = file_format.export_data(data, escape_output=self.should_escape_output)
151 return export_data
153 def get_context_data(self, **kwargs):
154 context = super().get_context_data(**kwargs)
155 return context
157 def get_form_kwargs(self):
158 kwargs = super().get_form_kwargs()
159 kwargs['formats'] = self.get_export_formats()
160 return kwargs
163class ExportViewFormMixin(ExportViewMixin, FormView):
164 def form_valid(self, form):
165 formats = self.get_export_formats()
166 file_format = formats[
167 int(form.cleaned_data['file_format'])
168 ]()
169 if hasattr(self, 'get_filterset'):
170 queryset = self.get_filterset(self.get_filterset_class()).qs
171 else:
172 queryset = self.get_queryset()
173 export_data = self.get_export_data(file_format, queryset)
174 content_type = file_format.get_content_type()
175 # Django 1.7 uses the content_type kwarg instead of mimetype
176 try:
177 response = HttpResponse(export_data, content_type=content_type)
178 except TypeError:
179 response = HttpResponse(export_data, mimetype=content_type)
180 response['Content-Disposition'] = 'attachment; filename="%s"' % (
181 self.get_export_filename(file_format),
182 )
184 post_export.send(sender=None, model=self.model)
185 return response