right-tree/backend/right_tree/api/admin.py

139 lines
4.6 KiB
Python
Raw Permalink Normal View History

from django.contrib import admin, messages
from django.http import HttpResponseRedirect, FileResponse
from django.utils.text import slugify
from django.utils import timezone
from right_tree.api import models
from right_tree.api.resource_generation_utils import storage
class ActivationKeySetFilter(admin.SimpleListFilter):
title = "key set"
parameter_name = "key_set"
def lookups(self, request, model_admin):
return [
(val, val) for val in models.ActivationKeySet.objects.values_list('name', flat=True)
]
def queryset(self, request, queryset):
key_set = self.value()
return queryset.filter(key__key_set__name=key_set) if key_set else queryset
class ZoneAdmin(admin.ModelAdmin):
ordering = ['name', 'variant', 'refined_variant', 'id']
search_fields = ['name', 'habitat__name', 'variant', 'refined_variant', 'id']
class ActivationKeySetAdmin(admin.ModelAdmin):
list_display = ['name', 'size_display']
@admin.display(description="Size")
def size_display(self, obj):
size = obj.size
return size if size > 0 else None
class ActivationKeyAdmin(admin.ModelAdmin):
list_display = ['key', 'creation_date', 'key_set', 'activations', 'remaining_activations']
list_filter = ['creation_date', 'key_set']
class QuestionnaireAdmin(admin.ModelAdmin):
list_display = ['address_display', 'location_display', 'soil_variant', 'ecological_district_display', 'habitat', 'zone', 'key_set_display', 'creation_date']
list_filter = [ActivationKeySetFilter]
actions = ['export']
@admin.display(description="Address")
def address_display(self, obj):
return obj.address.full_address
@admin.display(description="Location")
def location_display(self, obj):
return f"({obj.location.x:.4f}, {obj.location.y:.4f})"
@admin.display(description="Ecological District")
def ecological_district_display(self, obj):
return getattr(
models.EcologicalDistrictLayer.objects.filter(geom__intersects=obj.location).first(),
"ecologic_2",
None,
)
@admin.display(description="Key Set")
def key_set_display(self, obj):
if obj.key and obj.key.key_set:
return obj.key.key_set.name
@admin.action(description="Export planting guides for selected questionnaires")
def export(self, request, queryset):
export = models.Export.objects.create(creation_date=timezone.now())
export.questionnaires.set(queryset)
export.export()
return HttpResponseRedirect('/admin/api/export')
class ExportAdmin(admin.ModelAdmin):
list_display = ['creation_date', 'completion_date', 'completion_display']
actions = ['download']
@admin.display(description="Completion")
def completion_display(self, obj):
return f"{obj.completion:.1%}"
@admin.action(description="Download completed exports")
def download(self, request, queryset):
if queryset.count() > 1:
self.message_user(
request,
'Cannot download more than one export at a time.',
messages.ERROR,
)
return
export = queryset.first()
if not export.complete:
self.message_user(
request,
'Cannot download. Export is incomplete.',
messages.ERROR,
)
return
filename = f"export_{export.pk}/export.zip"
filepath = storage.path(filename)
if storage.exists(filename):
return FileResponse(
open(filepath, 'rb'),
filename=f"export_{slugify(export.creation_date)}.zip",
)
self.message_user(
request,
'Cannot download. Export is corrupt.',
messages.ERROR,
)
admin.site.register(models.Plant)
admin.site.register(models.SoilOrder)
admin.site.register(models.SoilLayer)
admin.site.register(models.SoilVariant)
admin.site.register(models.EcologicalRegion)
admin.site.register(models.EcologicalDistrictLayer)
admin.site.register(models.ToleranceLevel)
admin.site.register(models.HabitatImage)
admin.site.register(models.Habitat)
admin.site.register(models.Zone, ZoneAdmin)
admin.site.register(models.ChristchurchRegion)
admin.site.register(models.ActivationKey, ActivationKeyAdmin)
admin.site.register(models.ActivationKeySet, ActivationKeySetAdmin)
admin.site.register(models.Questionnaire, QuestionnaireAdmin)
admin.site.register(models.Export, ExportAdmin)
admin.site.register(models.Customer)
admin.site.register(models.CustomerAddress)