Coverage for jsanctions/admin.py : 39%

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
2import traceback
3from typing import Sequence
4from django.conf.urls import url
5from django.contrib import admin
6from django.contrib import messages
7from django.urls import ResolverMatch, reverse
8from django.utils.html import format_html
9from django.utils.safestring import mark_safe
10from django.utils.timezone import now
11from django.utils.translation import gettext_lazy as _
12from jutil.admin import ModelAdminBase
13from jsanctions.models import (
14 SubjectType,
15 Regulation,
16 RegulationSummary,
17 Remark,
18 NameAlias,
19 SanctionEntity,
20 BirthDate,
21 Identification,
22 Citizenship,
23 Address,
24 SanctionsListFile,
25)
28class SanctionsListAdminBase(ModelAdminBase):
29 exclude = ()
30 save_on_top = False
33class SubjectTypeAdmin(SanctionsListAdminBase):
34 exclude = ()
35 list_display = (
36 "classification_code",
37 "code",
38 )
41class SanctionsListFileAdmin(ModelAdminBase):
42 save_on_top = False
44 list_display = [
45 "created",
46 "generation_date",
47 "imported",
48 "file",
49 "list_type",
50 "entities",
51 ]
53 fields = [
54 "created",
55 "generation_date",
56 "imported",
57 "file",
58 "list_type",
59 "entities",
60 ]
62 readonly_fields = [
63 "created",
64 "generation_date",
65 "imported",
66 "list_type",
67 "entities",
68 ]
70 raw_id_fields = ()
72 list_filter = [
73 "list_type",
74 ]
76 date_hierarchy = "created"
78 def entities(self, obj):
79 assert isinstance(obj, SanctionsListFile)
80 return format_html('<a href="{}">{}</a>', reverse('admin:jsanctions_sanctionentity_source_changelist', args=[obj.id]), obj.sanctionentity_set.count())
82 entities.short_description = _("sanction entities")
85class RemarkAdmin(SanctionsListAdminBase):
86 raw_id_fields = ("container",)
87 list_display = (
88 "id",
89 "text_brief",
90 )
93class RemarkInlineAdmin(admin.TabularInline):
94 model = Remark
95 fk_name = "container"
96 extra = 0
97 fields = ("text",)
100class SanctionEntitySubFieldAdminBase(SanctionsListAdminBase):
101 raw_id_fields: Sequence[str] = ("sanction",)
104class SanctionEntityInlineAdmin(admin.StackedInline):
105 fk_name = "sanction"
106 extra = 0
109class NameAliasAdmin(SanctionEntitySubFieldAdminBase):
110 raw_id_fields = (
111 "sanction",
112 "regulation_summary",
113 )
116class NameAliasInlineAdmin(SanctionEntityInlineAdmin):
117 model = NameAlias
118 fields = (
119 "first_name",
120 "middle_name",
121 "last_name",
122 "whole_name",
123 "name_language",
124 "function",
125 "title",
126 "regulation_language",
127 "logical_id",
128 "regulation_summary",
129 )
130 raw_id_fields = (
131 "sanction",
132 "regulation_summary",
133 )
136class BirthDateAdmin(SanctionEntitySubFieldAdminBase):
137 list_display = (
138 "id",
139 "sanction",
140 "birth_date",
141 )
142 search_fields = ("birth_date",)
145class BirthDateInlineAdmin(SanctionEntityInlineAdmin):
146 model = BirthDate
147 fields = (
148 "circa",
149 "calendar_type",
150 "city",
151 "zip_code",
152 "birth_date",
153 "day_of_month",
154 "month_of_year",
155 "year",
156 "region",
157 "place",
158 "country_iso2_code",
159 "country_description",
160 "regulation_language",
161 "logical_id",
162 )
165class AddressAdmin(SanctionEntitySubFieldAdminBase):
166 list_display = (
167 "id",
168 "sanction",
169 "street",
170 "city",
171 "region",
172 "country_iso2_code",
173 )
174 search_fields = (
175 "street",
176 "city",
177 "region",
178 "country_iso2_code",
179 )
180 list_filter = ("country_iso2_code",)
183class AddressInlineAdmin(SanctionEntityInlineAdmin):
184 model = Address
185 fields = (
186 "city",
187 "street",
188 "po_box",
189 "zip_code",
190 "as_at_listing_time",
191 "place",
192 "region",
193 "country_iso2_code",
194 "country_description",
195 "regulation_language",
196 "logical_id",
197 "regulation_summary",
198 )
199 raw_id_fields = ("regulation_summary",)
202class IdentificationAdmin(SanctionEntitySubFieldAdminBase):
203 raw_id_fields = (
204 "sanction",
205 "regulation_summary",
206 )
209class IdentificationInlineAdmin(SanctionEntityInlineAdmin):
210 model = Identification
211 fields = (
212 "diplomatic",
213 "known_expired",
214 "known_false",
215 "reported_lost",
216 "revoked_by_issuer",
217 "issued_by",
218 "latin_number",
219 "name_on_document",
220 "number",
221 "region",
222 "country_iso2_code",
223 "country_description",
224 "identification_type_code",
225 "identification_type_description",
226 "regulation_language",
227 "logical_id",
228 "regulation_summary",
229 )
230 raw_id_fields = ("regulation_summary",)
233class CitizenshipAdmin(SanctionEntitySubFieldAdminBase):
234 raw_id_fields = (
235 "sanction",
236 "regulation_summary",
237 )
240class CitizenshipInlineAdmin(SanctionEntityInlineAdmin):
241 model = Citizenship
242 fields = (
243 "region",
244 "country_iso2_code",
245 "country_description",
246 "regulation_language",
247 "logical_id",
248 "regulation_summary",
249 )
250 raw_id_fields = (
251 "sanction",
252 "regulation_summary",
253 )
256class RegulationInlineAdmin(SanctionEntityInlineAdmin):
257 model = Regulation
258 fields = (
259 "regulation_type",
260 "organisation_type",
261 "publication_date",
262 "publication_url",
263 "entry_into_force_date",
264 "number_title",
265 "programme",
266 "logical_id",
267 )
270class RegulationSummaryAdmin(SanctionsListAdminBase):
271 exclude = ()
272 date_hierarchy = "publication_date"
273 search_fields = (
274 "number_title",
275 "publication_date__year",
276 )
277 list_display = (
278 "id",
279 "regulation_type",
280 "number_title",
281 "publication_date",
282 "publication_url",
283 )
286class DecadeBornListFilter(admin.SimpleListFilter):
287 title = _("decade born")
288 parameter_name = "born"
290 def lookups(self, request, model_admin):
291 opts = [
292 ("-1919", "-1919"),
293 ]
294 begin = 1920
295 this_year = now().year
296 while begin <= this_year:
297 end = begin + 9
298 if BirthDate.objects.filter(year__gte=begin, year__lte=end).first():
299 value = "{}-{}".format(begin, end)
300 label = "{} - {}".format(begin, end)
301 opts.append((value, label))
302 begin += 10
303 return opts
305 def queryset(self, request, queryset):
306 try:
307 if self.value():
308 begin, end = self.value().split("-")
309 if begin:
310 queryset = queryset.filter(birthdate__year__gte=int(begin))
311 if end:
312 queryset = queryset.filter(birthdate__year__lte=int(end))
313 except Exception as e:
314 messages.error(request, str(e))
315 queryset = SanctionEntity.objects.none()
316 return queryset
319class AddressCountryFilter(admin.SimpleListFilter):
320 title = _("residence country")
321 parameter_name = "rcountry"
323 def lookups(self, request, model_admin):
324 opts = []
325 for obj in Address.objects.distinct("country_iso2_code"):
326 assert isinstance(obj, Address)
327 opts.append((obj.country_iso2_code, obj.country_description))
328 return opts
330 def queryset(self, request, queryset):
331 try:
332 country = self.value()
333 if country:
334 queryset = SanctionEntity.objects.filter(address__country_iso2_code=country)
335 except Exception as e:
336 messages.error(request, str(e))
337 queryset = SanctionEntity.objects.none()
338 return queryset
341class CitizenshipCountryFilter(admin.SimpleListFilter):
342 title = _("citizenship country")
343 parameter_name = "ccountry"
345 def lookups(self, request, model_admin):
346 opts = []
347 for obj in Citizenship.objects.distinct("country_iso2_code"):
348 assert isinstance(obj, Citizenship)
349 opts.append((obj.country_iso2_code, obj.country_description))
350 return opts
352 def queryset(self, request, queryset):
353 try:
354 country = self.value()
355 if country:
356 queryset = SanctionEntity.objects.filter(citizenship__country_iso2_code=country)
357 except Exception as e:
358 messages.error(request, str(e))
359 queryset = SanctionEntity.objects.none()
360 return queryset
363class SanctionEntityAdmin(SanctionsListAdminBase):
364 search_fields = (
365 "namealias__whole_name__icontains",
366 "eu_reference_number__iexact",
367 "birthdate__year__iexact",
368 "birthdate__birth_date__iexact",
369 )
370 inlines = (
371 NameAliasInlineAdmin,
372 AddressInlineAdmin,
373 IdentificationInlineAdmin,
374 CitizenshipInlineAdmin,
375 BirthDateInlineAdmin,
376 RemarkInlineAdmin,
377 RegulationInlineAdmin,
378 )
379 raw_id_fields = (
380 "source",
381 "subject_type",
382 )
383 list_display = (
384 "id",
385 "source",
386 "designation_details",
387 "name_aliases",
388 "birth_year",
389 "united_nation_id",
390 "eu_reference_number",
391 "logical_id",
392 "subject_type",
393 )
394 list_filter = (
395 "subject_type",
396 DecadeBornListFilter,
397 AddressCountryFilter,
398 CitizenshipCountryFilter,
399 )
400 fields = [
401 'source',
402 'designation_details',
403 'united_nation_id',
404 'eu_reference_number',
405 'logical_id',
406 'subject_type',
407 'data_fmt',
408 ]
409 readonly_fields = [
410 'data_fmt',
411 ]
413 def data_fmt(self, obj) -> str:
414 try:
415 return mark_safe("<pre>" + json.dumps(obj.data, indent=4, sort_keys=True) + "</pre>")
416 except Exception:
417 return mark_safe("<pre>" + traceback.format_exc() + "</pre>")
419 data_fmt.short_description = _('data') # type: ignore
421 def name_aliases(self, obj) -> str:
422 assert isinstance(obj, SanctionEntity)
423 all_names = ", ".join([e.whole_name for e in obj.namealias_set.all()])
424 return all_names if len(all_names) < 64 else all_names[:64] + '...'
426 name_aliases.short_description = _("name aliases") # type: ignore
428 def birth_year(self, obj) -> str:
429 assert isinstance(obj, SanctionEntity)
430 return ", ".join([str(e.year) for e in obj.birthdate_set.all().distinct("year")])
432 birth_year.short_description = _("birth year") # type: ignore
434 def get_queryset(self, request):
435 rm = request.resolver_match
436 assert isinstance(rm, ResolverMatch)
437 qs = super().get_queryset(request)
438 source_id = rm.kwargs.get("source_id", None)
439 if source_id:
440 qs = qs.filter(source_id=source_id)
441 return qs
443 def get_urls(self):
444 info = self.model._meta.app_label, self.model._meta.model_name # type: ignore # noqa
445 return [
446 url(
447 r"^by-source/(?P<source_id>\d+)/$",
448 self.admin_site.admin_view(self.kw_changelist_view),
449 name="%s_%s_source_changelist" % info,
450 ),
451 ] + super().get_urls()
454admin.site.register(SanctionsListFile, SanctionsListFileAdmin)
455admin.site.register(SubjectType, SubjectTypeAdmin)
456admin.site.register(RegulationSummary, RegulationSummaryAdmin)
457admin.site.register(SanctionEntity, SanctionEntityAdmin)