Coverage for apps/report/admin.py : 69%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import json
3from django.urls import path
4from django.urls import reverse
5from django.contrib import admin
6from django.contrib.admin import helpers
7from django.utils.safestring import mark_safe
8from django.shortcuts import redirect, render
10from pygments import highlight
11from pygments.formatters import HtmlFormatter
12from pygments.lexers import JsonLexer
14from wv_dvs.admin import ModelAdmin
15from .models import (
16 Report,
17 ProjectSOI,
18 RegisterChildByAgeAndGender,
19 PresenceAndParticipation,
20 ChildFamilyParticipation,
21 LanguagePeopleGroupDisability,
22 SupportPariticipationDetail,
24 MostVulnerableChildrenIndicator,
25 MostVulnerableChildrenVulnerabilityMarker,
27 BulkImportReport,
28)
29from .forms import ReportAdminForm, BulkImportForm
32@admin.register(Report)
33class ReportAdmin(ModelAdmin):
34 exclude = ('data',)
35 search_fields = ('name', 'project__name', 'file')
36 list_display = ('name', 'get_project', 'file', 'date')
37 list_filter = ('project',)
38 autocomplete_fields = ('project',)
39 date_hierarchy = 'date'
40 form = ReportAdminForm
42 def get_readonly_fields(self, request, obj=None):
43 readonly_fields = super().get_readonly_fields(request, obj)
44 if obj is not None:
45 return [
46 *readonly_fields,
47 'file',
48 'data_prettified',
49 ]
50 return readonly_fields
52 def get_project(self, instance):
53 project = instance.project
54 link = reverse('admin:project_project_change', args=(project.id,))
55 return mark_safe('<a href="%s">%s</a>' % (link, project.name))
57 get_project.short_description = 'Project'
59 def data_prettified(self, instance):
60 """Function to display pretty version of our data"""
62 # Convert the data to sorted, indented JSON
63 response = json.dumps(instance.data, sort_keys=True, indent=2)
65 # Truncate the data. Alter as needed
66 # response = response[:5000]
68 # Get the Pygments formatter
69 formatter = HtmlFormatter(style='colorful')
71 # Highlight the data
72 response = highlight(response, JsonLexer(), formatter)
74 # Get the stylesheet
75 style = "<style>" + formatter.get_style_defs() + "</style><br>"
77 # Safe the output
78 over_styles = getattr(self, 'data_styles', '') if instance.data else ''
79 return mark_safe(
80 style +
81 '<div style="' + over_styles + '">' +
82 response +
83 '<div>'
84 )
86 data_prettified.short_description = 'data'
89class ProjectSummaryAdmin(ModelAdmin):
90 autocomplete_fields = ('project',)
91 list_filter = ('date',)
92 date_hierarchy = 'date'
94 def get_list_display(self, request):
95 return [
96 field.name for field in self.model._meta.fields if field.name != 'id'
97 ]
99 def changelist_view(self, request, extra_context=None):
100 extra_context = extra_context or {}
101 extra_context['additional_addlinks'] = [{
102 'url': self.get_import_namespace(),
103 'label': 'Bulk Import',
104 }]
105 return super().changelist_view(request, extra_context=extra_context)
107 def get_import_namespace(self, absolute=True):
108 info = self.model._meta.app_label, self.model._meta.model_name
109 return '{}{}_{}_import'.format('admin:' if absolute else '', *info)
111 def get_urls(self):
112 return [
113 path(
114 'import/', self.admin_site.admin_view(self.import_data),
115 name=self.get_import_namespace(False),
116 ),
117 ] + super().get_urls()
119 def import_data(self, request):
120 if request.method == 'POST':
121 form = BulkImportForm(request.POST, request.FILES, bulk_model=self.model)
122 if form.is_valid():
123 generated_on = form.data.get('generated_on')
124 BulkImportForm.handle_uploaded_file(request, generated_on, self.model)
125 return redirect(
126 'admin:{}_{}_changelist'.format(
127 self.model._meta.app_label, self.model._meta.model_name,
128 )
129 )
130 form = BulkImportForm(bulk_model=self.model)
132 context = {
133 **self.admin_site.each_context(request),
134 'has_view_permission': self.has_view_permission(request),
135 'app_label': self.model._meta.app_label,
136 'opts': self.model._meta,
137 'form': form,
138 'adminform': helpers.AdminForm(
139 form,
140 list([(None, {'fields': form.base_fields})]),
141 self.get_prepopulated_fields(request),
142 )
143 }
144 return render(request, "admin/bulk_import_form.html", context)
147@admin.register(ProjectSOI)
148class ProjectSOIAdmin(ProjectSummaryAdmin):
149 pass
152@admin.register(RegisterChildByAgeAndGender)
153class RegisterChildByAgeAndGenderAdmin(ProjectSummaryAdmin):
154 list_filter = ('age', 'gender')
157@admin.register(PresenceAndParticipation)
158class PresenceAndParticipationAdmin(ProjectSummaryAdmin):
159 pass
162@admin.register(ChildFamilyParticipation)
163class ChildFamilyParticipationAdmin(ProjectSummaryAdmin):
164 pass
167@admin.register(LanguagePeopleGroupDisability)
168class LanguagePeopleGroupDisabilityAdmin(ProjectSummaryAdmin):
169 list_filter = ('language', 'people_group', 'disability')
172@admin.register(SupportPariticipationDetail)
173class SupportPariticipationDetailAdmin(ProjectSummaryAdmin):
174 list_filter = ('type', 'comment',)
177@admin.register(MostVulnerableChildrenIndicator)
178class MostVulnerableChildrenIndicatorAdmin(ProjectSummaryAdmin):
179 pass
182@admin.register(MostVulnerableChildrenVulnerabilityMarker)
183class MostVulnerableChildrenVulnerabilityMarkerAdmin(ProjectSummaryAdmin):
184 pass
187@admin.register(BulkImportReport)
188class BulkImportReportAdmin(admin.ModelAdmin):
189 list_display = ('report_type', 'created_at', 'created_by', 'file')
190 exclude = ('log_message',)
191 readonly_fields = ('log_message_display',)
192 list_filter = ('created_at', 'status', 'report_type')
194 def get_model_perms(self, request):
195 return {}
197 def has_add_permission(self, requests, obj=None):
198 return False
200 def has_change_permission(self, requests, obj=None):
201 return False
203 def has_delete_permission(self, requests, obj=None):
204 return False
206 def log_message_display(self, obj):
207 if obj.log_message:
208 style_class = 'error' if obj.status == BulkImportReport.FAILED else ''
209 return mark_safe(
210 f'''
211 <ul class="messagelist">
212 <li class="{style_class}">
213 {obj.log_message}
214 </li>
215 </ul>
216 '''
217 )