konova/konova/forms.py

182 lines
5.5 KiB
Python
Raw Normal View History

2021-07-01 13:36:07 +02:00
"""
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 BSModalForm
2021-07-01 13:36:07 +02:00
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.utils import timezone
2021-07-01 13:36:07 +02:00
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)
self.user = kwargs.pop("user", None)
2021-07-01 13:36:07 +02:00
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):
2021-07-01 13:36:07 +02:00
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
2021-07-01 13:36:07 +02:00
self.object_to_remove.save()
return self.object_to_remove
class BaseModalForm(BaseForm, BSModalForm):
""" A specialzed form class for modal form handling
"""
is_modal_form = True
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 RemoveModalForm(BaseModalForm):
""" Generic removing modal form
Can be used for anything, where removing shall be confirmed by the user a second time.
"""
confirm = forms.BooleanField(
label=_("Confirm"),
label_suffix=_(""),
widget=forms.CheckboxInput(),
required=True,
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form_title = _("Remove")
self.form_caption = _("Are you sure?")
def save(self):
if hasattr(self.instance, "deleted_on"):
self.instance.deleted_on = timezone.now()
self.instance.deleted_by = self.user
self.instance.save()
else:
# If the class does not provide restorable delete functionality, we must delete the entry finally
self.instance.delete()
class RemoveDocumentForm(BaseModalForm):
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)