From a4966751b78631fcef3ead0c35d018bde70e8676 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 11 Jan 2022 12:56:27 +0100 Subject: [PATCH 1/9] # 61 Filter backend * refactors table filters by introducing AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin and RecordableTableFilterMixin * adds full filter functionality * refactors TableFilter inheritances for all objects --- compensation/filters.py | 18 +- intervention/filters.py | 107 +---------- konova/filters.py | 311 ++++++++++++++++++++++++++++++++ konova/models/geometry.py | 6 +- locale/de/LC_MESSAGES/django.mo | Bin 29386 -> 29698 bytes locale/de/LC_MESSAGES/django.po | 78 +++++--- 6 files changed, 379 insertions(+), 141 deletions(-) create mode 100644 konova/filters.py diff --git a/compensation/filters.py b/compensation/filters.py index 8bf0c232..1595b985 100644 --- a/compensation/filters.py +++ b/compensation/filters.py @@ -10,10 +10,11 @@ from django.utils.translation import gettext_lazy as _ from django import forms from django.db.models import QuerySet -from intervention.filters import InterventionTableFilter +from konova.filters import AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, \ + RecordableTableFilterMixin -class CompensationTableFilter(InterventionTableFilter): +class CompensationTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): """ TableFilter for compensations Based widely on InterventionTableFilter. @@ -21,7 +22,7 @@ class CompensationTableFilter(InterventionTableFilter): """ - def _filter_show_all(self, queryset, name, value) -> QuerySet: + def filter_show_all(self, queryset, name, value) -> QuerySet: """ Filters queryset depending on value of 'show_all' setting Args: @@ -39,7 +40,7 @@ class CompensationTableFilter(InterventionTableFilter): else: return queryset - def _filter_show_recorded(self, queryset, name, value) -> QuerySet: + def filter_show_recorded(self, queryset, name, value) -> QuerySet: """ Filters queryset depending on value of 'show_recorded' setting Args: @@ -58,21 +59,20 @@ class CompensationTableFilter(InterventionTableFilter): return queryset -class EcoAccountTableFilter(InterventionTableFilter): +class EcoAccountTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): """ TableFilter for eco accounts - Based widely on InterventionTableFilter. Just some minor changes for EcoAccount model. """ sr = django_filters.BooleanFilter( - method='_filter_only_show_unrecorded', + method='filter_only_show_unrecorded', label=_("Show only unrecorded"), label_suffix=_(""), widget=forms.CheckboxInput() ) - def _filter_show_all(self, queryset, name, value) -> QuerySet: + def filter_show_all(self, queryset, name, value) -> QuerySet: """ Filters queryset depending on value of 'show_all' setting Args: @@ -90,7 +90,7 @@ class EcoAccountTableFilter(InterventionTableFilter): else: return queryset - def _filter_only_show_unrecorded(self, queryset, name, value) -> QuerySet: + def filter_only_show_unrecorded(self, queryset, name, value) -> QuerySet: """ Filters queryset depending on value of 'show_recorded' setting Args: diff --git a/intervention/filters.py b/intervention/filters.py index 205b35c6..1dad9d36 100644 --- a/intervention/filters.py +++ b/intervention/filters.py @@ -5,119 +5,20 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 22.07.21 """ -import django_filters -from django import forms -from django.contrib.auth.models import User -from django.db.models import QuerySet, Q - -from django.utils.translation import gettext_lazy as _ - -from intervention.inputs import DummyFilterInput from intervention.models import Intervention +from konova.filters import AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, \ + RecordableTableFilterMixin -class InterventionTableFilter(django_filters.FilterSet): +class InterventionTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): """ TableFilter for Intervention model """ - sa = django_filters.BooleanFilter( - method='_filter_show_all', - label=_("Show unshared"), - label_suffix=_(""), - widget=forms.CheckboxInput() - ) - q = django_filters.Filter( - method='_filter_by_keyword', - # Since we use a custom search bar in the template, we need to 'render' this filter - # as 'anonymous' HiddenInput (no id, no name). This way our custom search bar's id and name won't be - # overwritten with these id and name (which would be equal) - # This way we can use the simple filter method mapping for a parameter without using a predefined widget! - widget=DummyFilterInput(), - ) - sr = django_filters.BooleanFilter( - method='_filter_show_recorded', - label=_("Show recorded"), - label_suffix=_(""), - widget=forms.CheckboxInput() - ) - # Gemarkung ##ToDo - g = django_filters.CharFilter( - field_name="name", - lookup_expr="icontains", - label=_(""), - label_suffix=_(""), - widget=forms.TextInput( - attrs={ - "placeholder": _("District"), - "title": _("Search for district") - } - ), - ) - # Kreis - ## ToDo - # Flur - ## ToDo - # Zähler - ## ToDo - # Nenner - ## ToDo class Meta: model = Intervention fields = [] - def __init__(self, user: User, *args, **kwargs): - self.user = user + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - def _filter_by_keyword(self, queryset, name, value) -> QuerySet: - """ Filters queryset depending on value of search bar input - - Args: - queryset (): - name (): - value (): - - Returns: - - """ - value = value.strip() - # build filter expression - q = Q(title__icontains=value) | Q(identifier__icontains=value) - return queryset.filter(q) - - def _filter_show_all(self, queryset, name, value) -> QuerySet: - """ Filters queryset depending on value of 'show_all' setting - - Args: - queryset (): - name (): - value (): - - Returns: - - """ - if not value: - return queryset.filter( - users__in=[self.user], # requesting user has access - ) - else: - return queryset - - def _filter_show_recorded(self, queryset, name, value) -> QuerySet: - """ Filters queryset depending on value of 'show_recorded' setting - - Args: - queryset (): - name (): - value (): - - Returns: - - """ - if not value: - return queryset.filter( - recorded=None, - ) - else: - return queryset diff --git a/konova/filters.py b/konova/filters.py new file mode 100644 index 00000000..ace6b4e9 --- /dev/null +++ b/konova/filters.py @@ -0,0 +1,311 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 11.01.22 + +""" +import django_filters +from django import forms +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth.models import User +from django.db.models import QuerySet, Q + +from intervention.inputs import DummyFilterInput +from konova.models import Parcel, District + + +class AbstractTableFilter(django_filters.FilterSet): + """ TableFilter for Intervention model + + """ + q = django_filters.Filter( + method='_filter_by_keyword', + # Since we use a custom search bar in the template, we need to 'render' this filter + # as 'anonymous' HiddenInput (no id, no name). This way our custom search bar's id and name won't be + # overwritten with these id and name (which would be equal) + # This way we can use the simple filter method mapping for a parameter without using a predefined widget! + widget=DummyFilterInput(), + ) + + class Meta: + abstract = True + + def __init__(self, user: User, *args, **kwargs): + self.user = user + super().__init__(*args, **kwargs) + + def _filter_by_keyword(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value of search bar input + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + value = value.strip() + # build filter expression + q = Q(title__icontains=value) | Q(identifier__icontains=value) + return queryset.filter(q) + + +class GeoReferencedTableFilterMixin(django_filters.FilterSet): + """ A mixin for AbstractTableFilter + + Specialized on filtering GeoReferenced model types + + """ + # Parcel gmrkng + di = django_filters.CharFilter( + method="filter_district", + label=_(""), + label_suffix=_(""), + widget=forms.TextInput( + attrs={ + "placeholder": _("District"), + "title": _("Search for district") + } + ), + ) + # Parcel gmrkng + pg = django_filters.CharFilter( + method="filter_gmrkng", + label=_(""), + label_suffix=_(""), + widget=forms.TextInput( + attrs={ + "placeholder": _("Parcel gmrkng"), + "title": _("Search for parcel gmrkng") + } + ), + ) + # Parcel + p = django_filters.CharFilter( + method="filter_parcel", + label=_(""), + label_suffix=_(""), + widget=forms.TextInput( + attrs={ + "placeholder": _("Parcel"), + "title": _("Search for parcel") + } + ), + ) + # Parcel counter + pc = django_filters.CharFilter( + method="filter_parcel_counter", + label=_(""), + label_suffix=_(""), + widget=forms.TextInput( + attrs={ + "placeholder": _("Parcel counter"), + "title": _("Search for parcel counter") + } + ), + ) + + # Parcel counter + pn = django_filters.CharFilter( + method="filter_parcel_number", + label=_(""), + label_suffix=_(""), + widget=forms.TextInput( + attrs={ + "placeholder": _("Parcel number"), + "title": _("Search for parcel number") + } + ), + ) + + class Meta: + abstract = True + + def _filter_parcel_reference(self, queryset, name, value, filter_value) -> QuerySet: + """ Filters the parcel entries by a given filter_value. + + filter_value may already include further filter annotations like 'xy__icontains' + + Args: + queryset (): + name (): + value (): + filter_value (): + + Returns: + + """ + _filter = { + filter_value: value + } + matching_parcels = Parcel.objects.filter( + **_filter + ) + related_geoms = matching_parcels.values( + "geometries" + ).distinct() + queryset = queryset.filter( + geometry__id__in=related_geoms + ) + return queryset + + def filter_district(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value for 'Gemarkung' + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + matching_districts = District.objects.filter( + krs=value + ) + matching_parcels = Parcel.objects.filter( + district__in=matching_districts + ) + related_geoms = matching_parcels.values( + "geometries" + ).distinct() + queryset = queryset.filter( + geometry__id__in=related_geoms + ) + return queryset + + def filter_gmrkng(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value for 'Gemarkung' + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + queryset = self._filter_parcel_reference(queryset, name, value, "gmrkng__istartswith") + return queryset + + def filter_parcel(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value for 'Parcel' + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + value = value.replace("-", "") + queryset = self._filter_parcel_reference(queryset, name, value, "flr") + return queryset + + def filter_parcel_counter(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value for 'Parcel' + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + value = value.replace("-", "") + queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_zhlr") + return queryset + + def filter_parcel_number(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value for 'Parcel' + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + value = value.replace("-", "") + queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_nnr") + return queryset + + +class ShareableTableFilterMixin(django_filters.FilterSet): + """ A mixin for AbstractTableFilter + + Specialized on filtering shareable model types + + """ + sa = django_filters.BooleanFilter( + method='filter_show_all', + label=_("Show unshared"), + label_suffix=_(""), + widget=forms.CheckboxInput() + ) + + class Meta: + abstract = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.user is None: + raise AttributeError("User must be set for further filtering!") + + def filter_show_all(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value of 'show_all' setting + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + if not value: + return queryset.filter( + users__in=[self.user], # requesting user has access + ) + else: + return queryset + + +class RecordableTableFilterMixin(django_filters.FilterSet): + """ A mixin for AbstractTableFilter + + Specialized on filtering recordable model types + + """ + sr = django_filters.BooleanFilter( + method='filter_show_recorded', + label=_("Show recorded"), + label_suffix=_(""), + widget=forms.CheckboxInput() + ) + + class Meta: + abstract = True + + def filter_show_recorded(self, queryset, name, value) -> QuerySet: + """ Filters queryset depending on value of 'show_recorded' setting + + Args: + queryset (): + name (): + value (): + + Returns: + + """ + if not value: + return queryset.filter( + recorded=None, + ) + else: + return queryset diff --git a/konova/models/geometry.py b/konova/models/geometry.py index aad39d6f..0a380b48 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -110,9 +110,13 @@ class Geometry(BaseResource): underlying_parcels = [] for result in fetched_parcels: fetched_parcel = result[typename] + # There could be parcels which include the word 'Flur', + # which needs to be deleted and just keep the numerical values + ## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE! + flr_val = fetched_parcel["ave:flur"].replace("Flur ", "") parcel_obj = Parcel.objects.get_or_create( gmrkng=fetched_parcel["ave:gemarkung"], - flr=fetched_parcel["ave:flur"], + flr=flr_val, flrstck_nnr=fetched_parcel['ave:flstnrnen'], flrstck_zhlr=fetched_parcel['ave:flstnrzae'], )[0] diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 2edf9a00a3a2bca27cb79905575d3ca11179826d..65defeed94e56e2d8d0c68b2d053d54b629a1b04 100644 GIT binary patch delta 9312 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 F{{!X>zo`HK diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index a83b6aab..453d065d 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -6,20 +6,22 @@ #: compensation/filters.py:71 compensation/forms/modalForms.py:34 #: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61 #: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316 -#: intervention/filters.py:26 intervention/filters.py:40 -#: intervention/filters.py:47 intervention/filters.py:48 +#: intervention/filters.py:25 intervention/filters.py:31 #: intervention/forms/forms.py:52 intervention/forms/forms.py:154 #: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125 #: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151 -#: konova/forms.py:140 konova/forms.py:241 konova/forms.py:312 -#: konova/forms.py:339 konova/forms.py:349 konova/forms.py:362 -#: konova/forms.py:374 konova/forms.py:392 user/forms.py:38 +#: konova/filters.py:64 konova/filters.py:65 konova/filters.py:76 +#: konova/filters.py:77 konova/filters.py:88 konova/filters.py:89 +#: konova/filters.py:100 konova/filters.py:101 konova/filters.py:113 +#: konova/filters.py:114 konova/forms.py:140 konova/forms.py:241 +#: konova/forms.py:312 konova/forms.py:339 konova/forms.py:349 +#: konova/forms.py:362 konova/forms.py:374 konova/forms.py:392 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-07 15:32+0100\n" +"POT-Creation-Date: 2022-01-11 09:31+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1197,22 +1199,14 @@ msgstr "EMA {} bearbeitet" msgid "EMA removed" msgstr "EMA entfernt" -#: intervention/filters.py:25 +#: intervention/filters.py:24 msgid "Show unshared" msgstr "Nicht freigegebene anzeigen" -#: intervention/filters.py:39 +#: intervention/filters.py:30 msgid "Show recorded" msgstr "Verzeichnete anzeigen" -#: intervention/filters.py:51 -msgid "District" -msgstr "Gemarkung" - -#: intervention/filters.py:52 -msgid "Search for district" -msgstr "Nach Gemarkung suchen" - #: intervention/forms/forms.py:44 msgid "Construction XY; Location ABC" msgstr "Bauvorhaben XY; Flur ABC" @@ -1521,6 +1515,46 @@ msgstr "" "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. " "Kontaktieren Sie bitte einen Administrator. +++" +#: konova/filters.py:68 +msgid "District" +msgstr "Kreis" + +#: konova/filters.py:69 +msgid "Search for district" +msgstr "Nach Kreis suchen" + +#: konova/filters.py:80 +msgid "Parcel gmrkng" +msgstr "Gemarkung" + +#: konova/filters.py:81 +msgid "Search for parcel gmrkng" +msgstr "Nach Gemarkung suchen" + +#: konova/filters.py:92 konova/templates/konova/includes/parcels.html:18 +msgid "Parcel" +msgstr "Flur" + +#: konova/filters.py:93 +msgid "Search for parcel" +msgstr "Nach Flur suchen" + +#: konova/filters.py:104 konova/templates/konova/includes/parcels.html:19 +msgid "Parcel counter" +msgstr "Flurstückzähler" + +#: konova/filters.py:105 +msgid "Search for parcel counter" +msgstr "Nach Flurstückzähler suchen" + +#: konova/filters.py:117 konova/templates/konova/includes/parcels.html:20 +msgid "Parcel number" +msgstr "Flurstücknenner" + +#: konova/filters.py:118 +msgid "Search for parcel number" +msgstr "Nach Flurstücknenner suchen" + #: konova/forms.py:37 templates/form/collapsable/form.html:62 msgid "Save" msgstr "Speichern" @@ -1687,18 +1721,6 @@ msgstr "Kreis" msgid "Gemarkung" msgstr "Gemarkung" -#: konova/templates/konova/includes/parcels.html:18 -msgid "Parcel" -msgstr "Flur" - -#: konova/templates/konova/includes/parcels.html:19 -msgid "Parcel counter" -msgstr "Flurstückzähler" - -#: konova/templates/konova/includes/parcels.html:20 -msgid "Parcel number" -msgstr "Flurstücknenner" - #: konova/templates/konova/widgets/generate-content-input.html:6 msgid "Generate new" msgstr "Neu generieren" From f92ec7fde7a4e12dfbaffaa0c2fd9574b1f5affc Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 11 Jan 2022 14:28:34 +0100 Subject: [PATCH 2/9] # 61 Filter frontend * optimizes minor parts of table-filter initialization and queryset passing --- compensation/tables.py | 6 ++++-- ema/tables.py | 3 ++- intervention/filters.py | 1 - intervention/tables.py | 3 ++- konova/utils/tables.py | 4 +--- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compensation/tables.py b/compensation/tables.py index df7ec3eb..2784af23 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -67,7 +67,8 @@ class CompensationTable(BaseTable): data=request.GET, queryset=qs, ) - super().__init__(request, self.filter, *args, **kwargs) + kwargs["queryset"] = self.filter.qs + super().__init__(request, *args, **kwargs) def render_id(self, value, record: Compensation): """ Renders the id column for a compensation @@ -207,7 +208,8 @@ class EcoAccountTable(BaseTable): data=request.GET, queryset=qs, ) - super().__init__(request, self.filter, *args, **kwargs) + kwargs["queryset"] = self.filter.qs + super().__init__(request, *args, **kwargs) def render_id(self, value, record: EcoAccount): """ Renders the id column for an eco account diff --git a/ema/tables.py b/ema/tables.py index 9055059d..884bac54 100644 --- a/ema/tables.py +++ b/ema/tables.py @@ -65,7 +65,8 @@ class EmaTable(BaseTable): data=request.GET, queryset=qs, ) - super().__init__(request, self.filter, *args, **kwargs) + kwargs["queryset"] = self.filter.qs + super().__init__(request, *args, **kwargs) def render_id(self, value, record: Ema): """ Renders the id column for a EMA diff --git a/intervention/filters.py b/intervention/filters.py index 1dad9d36..01a3abe5 100644 --- a/intervention/filters.py +++ b/intervention/filters.py @@ -21,4 +21,3 @@ class InterventionTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - diff --git a/intervention/tables.py b/intervention/tables.py index 103d419a..b0da7d04 100644 --- a/intervention/tables.py +++ b/intervention/tables.py @@ -71,7 +71,8 @@ class InterventionTable(BaseTable): data=request.GET, queryset=qs, ) - super().__init__(request, self.filter, *args, **kwargs) + kwargs["queryset"] = self.filter.qs + super().__init__(request, *args, **kwargs) def render_id(self, value, record: Intervention): """ Renders the id column for an intervention diff --git a/konova/utils/tables.py b/konova/utils/tables.py index 9d0329f3..6a3ef88e 100644 --- a/konova/utils/tables.py +++ b/konova/utils/tables.py @@ -31,10 +31,8 @@ class BaseTable(tables.tables.Table): "class": "table table-hover table-responsive-md table-responsive-sm", } - def __init__(self, request: HttpRequest = None, filter_set=None, queryset=None, *args, **kwargs): + def __init__(self, request: HttpRequest = None, queryset=None, *args, **kwargs): self.user = request.user or None - if filter_set is not None: - queryset = filter_set.qs kwargs["data"] = queryset kwargs["request"] = request super().__init__(*args, **kwargs) From d8607d9ade13f7c82d37c4abe69e17794164e2f0 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 11 Jan 2022 15:19:16 +0100 Subject: [PATCH 3/9] # 61 Filter backend * refactors XYTableFilter classes to hold query_filter and checkbox_filter which are separate instances of django_filter.FilterSets * improves render ability for frontend --- compensation/filters.py | 66 ++++++++++++++++++++++++++++++------ intervention/filters.py | 32 ++++++++++------- konova/filters.py | 31 +++++++++++++---- templates/generic_index.html | 11 ++++-- 4 files changed, 110 insertions(+), 30 deletions(-) diff --git a/compensation/filters.py b/compensation/filters.py index 1595b985..b44b900a 100644 --- a/compensation/filters.py +++ b/compensation/filters.py @@ -10,15 +10,11 @@ from django.utils.translation import gettext_lazy as _ from django import forms from django.db.models import QuerySet -from konova.filters import AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, \ - RecordableTableFilterMixin +from konova.filters import QueryTableFilter, CheckboxTableFilter -class CompensationTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): - """ TableFilter for compensations - - Based widely on InterventionTableFilter. - Just some minor changes for Compensation model. +class CheckboxCompensationTableFilter(CheckboxTableFilter): + """ Specialization of regular CheckboxTableFilter for compensation model """ @@ -59,12 +55,36 @@ class CompensationTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin return queryset -class EcoAccountTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): - """ TableFilter for eco accounts +class CompensationTableFilter: + """ TableFilter for compensations - Just some minor changes for EcoAccount model. + Based widely on InterventionTableFilter. + Just some minor changes for Compensation model. """ + query_filter = None + checkbox_filter = None + qs = None + + def __init__(self, *args, **kwargs): + user = kwargs.get("user", None) + qs = kwargs.get("queryset", None) + request_data = kwargs.get("data", None) + + self.query_filter = QueryTableFilter( + user=user, + data=request_data, + queryset=qs, + ) + self.checkbox_filter = CheckboxCompensationTableFilter( + user=user, + data=request_data, + queryset=self.query_filter.qs, + ) + self.qs = self.checkbox_filter.qs + + +class CheckboxEcoAccountTableFilter(CheckboxTableFilter): sr = django_filters.BooleanFilter( method='filter_only_show_unrecorded', label=_("Show only unrecorded"), @@ -107,3 +127,29 @@ class EcoAccountTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ) else: return queryset + + +class EcoAccountTableFilter: + """ TableFilter for eco accounts + + """ + query_filter = None + checkbox_filter = None + qs = None + + def __init__(self, *args, **kwargs): + user = kwargs.get("user", None) + qs = kwargs.get("queryset", None) + request_data = kwargs.get("data", None) + + self.query_filter = QueryTableFilter( + user=user, + data=request_data, + queryset=qs, + ) + self.checkbox_filter = CheckboxEcoAccountTableFilter( + user=user, + data=request_data, + queryset=self.query_filter.qs, + ) + self.qs = self.checkbox_filter.qs diff --git a/intervention/filters.py b/intervention/filters.py index 01a3abe5..c6b61156 100644 --- a/intervention/filters.py +++ b/intervention/filters.py @@ -5,19 +5,27 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 22.07.21 """ -from intervention.models import Intervention -from konova.filters import AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, \ - RecordableTableFilterMixin +from konova.filters import QueryTableFilter, CheckboxTableFilter -class InterventionTableFilter(AbstractTableFilter, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, RecordableTableFilterMixin): - """ TableFilter for Intervention model - - """ - - class Meta: - model = Intervention - fields = [] +class InterventionTableFilter: + query_filter = None + checkbox_filter = None + qs = None def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + user = kwargs.get("user", None) + qs = kwargs.get("queryset", None) + request_data = kwargs.get("data", None) + + self.query_filter = QueryTableFilter( + user=user, + data=request_data, + queryset=qs, + ) + self.checkbox_filter = CheckboxTableFilter( + user=user, + data=request_data, + queryset=self.query_filter.qs, + ) + self.qs = self.checkbox_filter.qs diff --git a/konova/filters.py b/konova/filters.py index ace6b4e9..9b3461c6 100644 --- a/konova/filters.py +++ b/konova/filters.py @@ -19,8 +19,17 @@ class AbstractTableFilter(django_filters.FilterSet): """ TableFilter for Intervention model """ + class Meta: + abstract = True + + def __init__(self, user: User, *args, **kwargs): + self.user = user + super().__init__(*args, **kwargs) + + +class KeywordTableFilterMixin(django_filters.FilterSet): q = django_filters.Filter( - method='_filter_by_keyword', + method='filter_by_keyword', # Since we use a custom search bar in the template, we need to 'render' this filter # as 'anonymous' HiddenInput (no id, no name). This way our custom search bar's id and name won't be # overwritten with these id and name (which would be equal) @@ -31,11 +40,7 @@ class AbstractTableFilter(django_filters.FilterSet): class Meta: abstract = True - def __init__(self, user: User, *args, **kwargs): - self.user = user - super().__init__(*args, **kwargs) - - def _filter_by_keyword(self, queryset, name, value) -> QuerySet: + def filter_by_keyword(self, queryset, name, value) -> QuerySet: """ Filters queryset depending on value of search bar input Args: @@ -309,3 +314,17 @@ class RecordableTableFilterMixin(django_filters.FilterSet): ) else: return queryset + + +class QueryTableFilter(AbstractTableFilter, KeywordTableFilterMixin, GeoReferencedTableFilterMixin): + """ TableFilter holding different filter options for query related filtering + + """ + pass + + +class CheckboxTableFilter(AbstractTableFilter, ShareableTableFilterMixin, RecordableTableFilterMixin): + """ TableFilter holding different filter options for checkbox related filtering + + """ + pass diff --git a/templates/generic_index.html b/templates/generic_index.html index cf3253a3..66ab6525 100644 --- a/templates/generic_index.html +++ b/templates/generic_index.html @@ -41,7 +41,7 @@
- +
- {{ table.filter.form.as_p }} +
+ {{table.filter.query_filter.form.as_p}} +
+
+ {{table.filter.checkbox_filter.form.as_p}} +
+
+
From 972405a720cf58c1f71f91ca9cd9b54c3761abbf Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 11 Jan 2022 16:32:33 +0100 Subject: [PATCH 4/9] # 61 Filter frontend * finished filter frontend --- konova/filters.py | 27 ++++++++++++++++++++------- templates/filter/checkbox_filter.html | 5 +++++ templates/filter/query_filter.html | 10 ++++++++++ templates/generic_index.html | 13 +++++++++---- 4 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 templates/filter/checkbox_filter.html create mode 100644 templates/filter/query_filter.html diff --git a/konova/filters.py b/konova/filters.py index 9b3461c6..00445828 100644 --- a/konova/filters.py +++ b/konova/filters.py @@ -71,7 +71,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): widget=forms.TextInput( attrs={ "placeholder": _("District"), - "title": _("Search for district") + "title": _("Search for district"), + "class": "form-control", } ), ) @@ -83,7 +84,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): widget=forms.TextInput( attrs={ "placeholder": _("Parcel gmrkng"), - "title": _("Search for parcel gmrkng") + "title": _("Search for parcel gmrkng"), + "class": "form-control", } ), ) @@ -95,7 +97,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): widget=forms.TextInput( attrs={ "placeholder": _("Parcel"), - "title": _("Search for parcel") + "title": _("Search for parcel"), + "class": "form-control", } ), ) @@ -107,7 +110,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): widget=forms.TextInput( attrs={ "placeholder": _("Parcel counter"), - "title": _("Search for parcel counter") + "title": _("Search for parcel counter"), + "class": "form-control", } ), ) @@ -120,7 +124,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): widget=forms.TextInput( attrs={ "placeholder": _("Parcel number"), - "title": _("Search for parcel number") + "title": _("Search for parcel number"), + "class": "form-control", } ), ) @@ -251,7 +256,11 @@ class ShareableTableFilterMixin(django_filters.FilterSet): method='filter_show_all', label=_("Show unshared"), label_suffix=_(""), - widget=forms.CheckboxInput() + widget=forms.CheckboxInput( + attrs={ + "class": "form-check-input", + } + ) ) class Meta: @@ -291,7 +300,11 @@ class RecordableTableFilterMixin(django_filters.FilterSet): method='filter_show_recorded', label=_("Show recorded"), label_suffix=_(""), - widget=forms.CheckboxInput() + widget=forms.CheckboxInput( + attrs={ + "class": "form-check-input", + } + ) ) class Meta: diff --git a/templates/filter/checkbox_filter.html b/templates/filter/checkbox_filter.html new file mode 100644 index 00000000..93410368 --- /dev/null +++ b/templates/filter/checkbox_filter.html @@ -0,0 +1,5 @@ +{% for field in form %} +
+ {{field}} +
+{% endfor %} \ No newline at end of file diff --git a/templates/filter/query_filter.html b/templates/filter/query_filter.html new file mode 100644 index 00000000..24c867a9 --- /dev/null +++ b/templates/filter/query_filter.html @@ -0,0 +1,10 @@ +
+ {% for field in form %} + {% if not field.is_hidden %} +
+ {{field}} +
+ {% else %} + {% endif %} + {% endfor %} +
\ No newline at end of file diff --git a/templates/generic_index.html b/templates/generic_index.html index 66ab6525..cd2c3269 100644 --- a/templates/generic_index.html +++ b/templates/generic_index.html @@ -83,12 +83,17 @@
- {{table.filter.query_filter.form.as_p}} + {% with table.filter.query_filter.form as form %} + {% include 'filter/query_filter.html' %} + {% endwith %}
-
- {{table.filter.checkbox_filter.form.as_p}} +
+ {% with table.filter.checkbox_filter.form as form %} + {% include 'filter/checkbox_filter.html' %} + {% endwith %}
-
+
+
+
+
+ {% with table.filter.selection_filter.form as form %} + {% include 'filter/query_filter.html' %} + {% endwith %} +
+
+
+ {% with table.filter.query_filter.form as form %} + {% include 'filter/query_filter.html' %} + {% endwith %} +
+
+
+ {% with table.filter.checkbox_filter.form as form %} + {% include 'filter/checkbox_filter.html' %} + {% endwith %} +
+
+
+ +
From b96dcd373a487769b2eec9a66cb0a8433052c70f Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 12 Jan 2022 10:15:57 +0100 Subject: [PATCH 9/9] # 61 EcoAccount Filter * adds specialized SelectionTableFilter for EcoAccount (and EMA) which only provides filtering by conservation office --- compensation/filters.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compensation/filters.py b/compensation/filters.py index eb8a5b7d..d028e3ce 100644 --- a/compensation/filters.py +++ b/compensation/filters.py @@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy as _ from django import forms from django.db.models import QuerySet, Q +from konova.filters.mixins import ConservationOfficeTableFilterMixin from konova.filters.table_filters import QueryTableFilter, CheckboxTableFilter, SelectionTableFilter, AbstractTableFilter @@ -163,6 +164,15 @@ class CheckboxEcoAccountTableFilter(CheckboxTableFilter): return queryset +class SelectionEcoAccountTableFilter(ConservationOfficeTableFilterMixin): + """ Special selection table filter for eco accounts + + EcoAccounts only need a selection filter for conservation office + + """ + pass + + class EcoAccountTableFilter(AbstractTableFilter): """ TableFilter for eco accounts @@ -174,7 +184,7 @@ class EcoAccountTableFilter(AbstractTableFilter): request_data = kwargs.get("data", None) # Pipe the queryset through all needed filters - self.selection_filter = SelectionTableFilter( + self.selection_filter = SelectionEcoAccountTableFilter( data=request_data, queryset=qs, )