#146 Admins and update_all_parcels.py

* extends admin backend
    * adds found_in_codelists to KonovaCodeAdmin to see where a KonovaCode can be found in
    * improves rendering of after_states and before_states for all AbstractCompensationAdmins
    * adds geometry_id to all major datatype admin backends
    * adds st_area like calculation to geometry admin backend
* update_all_parcels
    * orders geometries by size (small to big) to process smaller geometries first and bigger later
    * adds more output to command for a better overview of what is just going on
This commit is contained in:
mpeltriaux 2022-04-13 11:42:04 +02:00
parent fb1dce9d3c
commit 60e23d15fc
6 changed files with 59 additions and 4 deletions

View File

@ -33,6 +33,7 @@ class KonovaCodeAdmin(admin.ModelAdmin):
"is_selectable", "is_selectable",
"is_leaf", "is_leaf",
"parent", "parent",
"found_in_codelists",
] ]
search_fields = [ search_fields = [
@ -42,6 +43,12 @@ class KonovaCodeAdmin(admin.ModelAdmin):
"short_name", "short_name",
] ]
def found_in_codelists(self, obj):
codelists = KonovaCodeList.objects.filter(
codes__in=[obj]
).values_list("id", flat=True)
codelists = "\n".join(str(x) for x in codelists)
return codelists
#admin.site.register(KonovaCodeList, KonovaCodeListAdmin) #admin.site.register(KonovaCodeList, KonovaCodeListAdmin)
admin.site.register(KonovaCode, KonovaCodeAdmin) admin.site.register(KonovaCode, KonovaCodeAdmin)

View File

@ -21,16 +21,30 @@ class AbstractCompensationAdmin(BaseObjectAdmin):
"identifier", "identifier",
"title", "title",
"comment", "comment",
"after_states", "list_after_states",
"before_states", "list_before_states",
"geometry",
] ]
def get_readonly_fields(self, request, obj=None): def get_readonly_fields(self, request, obj=None):
return super().get_readonly_fields(request, obj) + [ return super().get_readonly_fields(request, obj) + [
"after_states", "list_after_states",
"before_states", "list_before_states",
"geometry",
] ]
def list_after_states(self, obj):
states = obj.after_states.all()
states = [str(state) for state in states]
states = "\n".join(states)
return states
def list_before_states(self, obj):
states = obj.before_states.all()
states = [str(state) for state in states]
states = "\n".join(states)
return states
class CompensationAdmin(AbstractCompensationAdmin): class CompensationAdmin(AbstractCompensationAdmin):
autocomplete_fields = [ autocomplete_fields = [

View File

@ -25,12 +25,14 @@ class InterventionAdmin(BaseObjectAdmin):
"checked", "checked",
"recorded", "recorded",
"users", "users",
"geometry",
] ]
def get_readonly_fields(self, request, obj=None): def get_readonly_fields(self, request, obj=None):
return super().get_readonly_fields(request, obj) + [ return super().get_readonly_fields(request, obj) + [
"checked", "checked",
"recorded", "recorded",
"geometry",
] ]

View File

@ -8,6 +8,7 @@ Created on: 22.07.21
from django.contrib import admin from django.contrib import admin
from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
from user.models import UserAction from user.models import UserAction
@ -16,7 +17,22 @@ class GeometryAdmin(admin.ModelAdmin):
list_display = [ list_display = [
"id", "id",
"created", "created",
"st_area",
] ]
readonly_fields = [
"st_area",
"created",
"modified",
]
def st_area(self, obj):
val = None
geom = obj.geom
if geom is not None:
geom.transform(ct=DEFAULT_SRID_RLP)
val = geom.area
return val
st_area.short_description = f"Area (srid={DEFAULT_SRID_RLP})"
class ParcelAdmin(admin.ModelAdmin): class ParcelAdmin(admin.ModelAdmin):

View File

@ -5,6 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 04.01.22 Created on: 04.01.22
""" """
import datetime
from django.contrib.gis.db.models.functions import Area
from konova.management.commands.setup import BaseKonovaCommand from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Geometry, Parcel, District from konova.models import Geometry, Parcel, District
@ -23,12 +27,21 @@ class Command(BaseKonovaCommand):
num_parcels_before = Parcel.objects.count() num_parcels_before = Parcel.objects.count()
num_districts_before = District.objects.count() num_districts_before = District.objects.count()
self._write_warning("=== Update parcels and districts ===") self._write_warning("=== Update parcels and districts ===")
# Order geometries by size to process smaller once at first
geometries = Geometry.objects.all().exclude( geometries = Geometry.objects.all().exclude(
geom=None geom=None
).annotate(area=Area("geom")).order_by(
'area'
) )
self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...") self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
i = 0
num_geoms = geometries.count()
for geometry in geometries: for geometry in geometries:
self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
geometry.update_parcels() geometry.update_parcels()
self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels")
i += 1
self._write_warning(f"--- {i}/{num_geoms} processed")
num_parcels_after = Parcel.objects.count() num_parcels_after = Parcel.objects.count()
num_districts_after = District.objects.count() num_districts_after = District.objects.count()

View File

@ -20,6 +20,9 @@ class Geometry(BaseResource):
from konova.settings import DEFAULT_SRID from konova.settings import DEFAULT_SRID
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID)
def __str__(self):
return str(self.id)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super().save(*args, **kwargs) super().save(*args, **kwargs)
self.check_for_conflicts() self.check_for_conflicts()