konova/konova/forms.py
mipel 76c7cce9bc Documents removing
* adds generic modal rendering using package django-bootstrap-modal-forms
* adds document file removing from hard drive
* adds translations
2021-07-23 18:27:53 +02:00

147 lines
4.5 KiB
Python

"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 16.11.20
"""
from abc import abstractmethod
from bootstrap_modal_forms.forms import BSModalModelForm, BSModalForm
from django import forms
from django.contrib.auth.models import User
from django.contrib.gis.forms import GeometryField, OSMWidget
from django.contrib.gis.geos import Polygon
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
class BaseForm(forms.Form):
"""
Basic form for that holds attributes needed in all other forms
"""
action_url = None
form_title = None
cancel_redirect = None
form_caption = None
instance = None # The data holding model object
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop("instance", None)
super().__init__(*args, **kwargs)
@abstractmethod
def save(self):
# To be implemented in subclasses!
pass
def disable_form_field(self, field: str):
"""
Disables a form field for user editing
"""
self.fields[field].widget.attrs["readonly"] = True
self.fields[field].disabled = True
self.fields[field].widget.attrs["title"] = _("Not editable")
def initialize_form_field(self, field: str, val):
"""
Initializes a form field with a value
"""
self.fields[field].initial = val
def load_initial_data(self, form_data: dict, disabled_fields: list):
""" Initializes form data from instance
Inserts instance data into form and disables form fields
Returns:
"""
if self.instance is None:
return
for k, v in form_data.items():
self.initialize_form_field(k, v)
for field in disabled_fields:
self.disable_form_field(field)
class RemoveForm(BaseForm):
check = forms.BooleanField(
label=_("Confirm"),
label_suffix=_(""),
required=True,
)
def __init__(self, *args, **kwargs):
self.object_to_remove = kwargs.pop("object_to_remove", None)
self.remove_post_url = kwargs.pop("remove_post_url", "")
self.cancel_url = kwargs.pop("cancel_url", "")
super().__init__(*args, **kwargs)
self.form_title = _("Remove")
if self.object_to_remove is not None:
self.form_caption = _("You are about to remove {} {}").format(self.object_to_remove.__class__.__name__, self.object_to_remove)
self.action_url = self.remove_post_url
self.cancel_redirect = self.cancel_url
def is_checked(self) -> bool:
return self.cleaned_data.get("check", False)
def save(self, user: User):
if self.object_to_remove is not None and self.is_checked():
self.object_to_remove.is_active = False
self.object_to_remove.deleted_on = timezone.now()
self.object_to_remove.deleted_by = user
self.object_to_remove.save()
return self.object_to_remove
class SimpleGeomForm(BaseForm):
""" A geometry form for rendering geometry read-only using a widget
"""
geom = GeometryField(
required=False,
disabled=True,
widget=OSMWidget(
attrs={
"map_width": 600,
"map_height": 400,
}
)
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Initialize geometry
try:
geom = self.instance.geometry.geom
if geom is None:
raise AttributeError
except AttributeError:
# catches if no geometry has been added, yet. Replace with empty placeholder polygon.
geom = Polygon.from_bbox([0, 0, 0, 0])
# Zoom out to a very high level, so the user can see directly that there is no geometry for this entry
self.fields["geom"].widget.attrs["default_zoom"] = 1
self.initialize_form_field("geom", geom)
self.area = geom.area
class RemoveDocumentForm(BaseForm, BSModalForm):
confirm = forms.BooleanField(
label=_("Confirm"),
label_suffix=_(""),
widget=forms.CheckboxInput(),
required=True,
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.instance = kwargs.get("instance", None)
self.form_title = _("Remove document")
self.form_caption = _("This will remove '{}'. Are you sure?").format(self.instance.title)