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

1import warnings 

2 

3from django.conf import settings 

4from django.http import HttpResponse 

5from django.utils.timezone import now 

6from django.views.generic.edit import FormView 

7 

8from .formats import base_formats 

9from .forms import ExportForm 

10from .resources import modelresource_factory 

11from .signals import post_export 

12 

13 

14class BaseImportExportMixin: 

15 formats = base_formats.DEFAULT_FORMATS 

16 resource_class = None 

17 resource_classes = [] 

18 

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, ...)") 

22 

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] 

45 

46 def get_resource_kwargs(self, request, *args, **kwargs): 

47 return {} 

48 

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 

57 

58 

59class BaseImportMixin(BaseImportExportMixin): 

60 

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()] 

72 

73 resource_classes = self.get_resource_classes() 

74 self.check_resource_classes(resource_classes) 

75 return resource_classes 

76 

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()] 

82 

83 def get_import_resource_kwargs(self, request, *args, **kwargs): 

84 return self.get_resource_kwargs(request, *args, **kwargs) 

85 

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] 

89 

90 

91class BaseExportMixin(BaseImportExportMixin): 

92 model = None 

93 escape_exported_data = False 

94 

95 @property 

96 def should_escape_output(self): 

97 return getattr(settings, 'IMPORT_EXPORT_ESCAPE_OUTPUT_ON_EXPORT', self.escape_exported_data) 

98 

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()] 

104 

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()] 

116 

117 resource_classes = self.get_resource_classes() 

118 self.check_resource_classes(resource_classes) 

119 return resource_classes 

120 

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] 

124 

125 def get_export_resource_kwargs(self, request, *args, **kwargs): 

126 return self.get_resource_kwargs(request, *args, **kwargs) 

127 

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) 

133 

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 

140 

141 

142class ExportViewMixin(BaseExportMixin): 

143 form_class = ExportForm 

144 

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 

152 

153 def get_context_data(self, **kwargs): 

154 context = super().get_context_data(**kwargs) 

155 return context 

156 

157 def get_form_kwargs(self): 

158 kwargs = super().get_form_kwargs() 

159 kwargs['formats'] = self.get_export_formats() 

160 return kwargs 

161 

162 

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 ) 

183 

184 post_export.send(sender=None, model=self.model) 

185 return response