Merge pull request '61_Extend_filter' (#64) from 61_Extend_filter into master
Reviewed-on: SGD-Nord/konova#64
This commit is contained in:
commit
37fffd639f
@ -8,20 +8,45 @@ Created on: 29.07.21
|
||||
import django_filters
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django import forms
|
||||
from django.db.models import QuerySet
|
||||
from django.db.models import QuerySet, Q
|
||||
|
||||
from intervention.filters import InterventionTableFilter
|
||||
from konova.filters.mixins import ConservationOfficeTableFilterMixin
|
||||
from konova.filters.table_filters import QueryTableFilter, CheckboxTableFilter, SelectionTableFilter, AbstractTableFilter
|
||||
|
||||
|
||||
class CompensationTableFilter(InterventionTableFilter):
|
||||
""" TableFilter for compensations
|
||||
class SelectionCompensationTableFilter(SelectionTableFilter):
|
||||
""" Specialization of regular SelectionTableFilter for compensation model
|
||||
|
||||
Based widely on InterventionTableFilter.
|
||||
Just some minor changes for Compensation model.
|
||||
"""
|
||||
def filter_reg_office(self, queryset, name, value):
|
||||
return queryset.filter(
|
||||
intervention__responsible__registration_office=value
|
||||
)
|
||||
|
||||
def filter_cons_office(self, queryset, name, value):
|
||||
return queryset.filter(
|
||||
intervention__responsible__conservation_office=value
|
||||
)
|
||||
|
||||
|
||||
class QueryCompensationTableFilter(QueryTableFilter):
|
||||
""" Specialization of regular QueryTableFilter for compensation model
|
||||
|
||||
"""
|
||||
def filter_file_number(self, queryset, name, value) -> QuerySet:
|
||||
queryset = queryset.filter(
|
||||
Q(intervention__responsible__registration_file_number__icontains=value) |
|
||||
Q(intervention__responsible__conservation_file_number__icontains=value)
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
||||
class CheckboxCompensationTableFilter(CheckboxTableFilter):
|
||||
""" Specialization of regular CheckboxTableFilter for compensation model
|
||||
|
||||
"""
|
||||
|
||||
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 +64,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 +83,51 @@ class CompensationTableFilter(InterventionTableFilter):
|
||||
return queryset
|
||||
|
||||
|
||||
class EcoAccountTableFilter(InterventionTableFilter):
|
||||
""" TableFilter for eco accounts
|
||||
class CompensationTableFilter(AbstractTableFilter):
|
||||
""" TableFilter for compensations
|
||||
|
||||
Based widely on InterventionTableFilter.
|
||||
Just some minor changes for EcoAccount model.
|
||||
Just some minor changes for Compensation model.
|
||||
|
||||
"""
|
||||
def __init__(self, user=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.user = user
|
||||
qs = kwargs.get("queryset", None)
|
||||
request_data = kwargs.get("data", None)
|
||||
|
||||
# Overwrite all filters for special needs of compensations
|
||||
self.selection_filter = SelectionCompensationTableFilter(
|
||||
data=request_data,
|
||||
queryset=qs,
|
||||
)
|
||||
self.query_filter = QueryCompensationTableFilter(
|
||||
data=request_data,
|
||||
queryset=self.selection_filter.qs,
|
||||
)
|
||||
self.checkbox_filter = CheckboxCompensationTableFilter(
|
||||
user=user,
|
||||
data=request_data,
|
||||
queryset=self.query_filter.qs,
|
||||
)
|
||||
# Overwrite final queryset as well
|
||||
self.qs = self.checkbox_filter.qs
|
||||
|
||||
|
||||
class CheckboxEcoAccountTableFilter(CheckboxTableFilter):
|
||||
sr = django_filters.BooleanFilter(
|
||||
method='_filter_only_show_unrecorded',
|
||||
method='filter_only_show_unrecorded',
|
||||
label=_("Show only unrecorded"),
|
||||
label_suffix=_(""),
|
||||
widget=forms.CheckboxInput()
|
||||
widget=forms.CheckboxInput(
|
||||
attrs={
|
||||
"class": "form-check-input",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
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 +145,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:
|
||||
@ -107,3 +162,40 @@ class EcoAccountTableFilter(InterventionTableFilter):
|
||||
)
|
||||
else:
|
||||
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
|
||||
|
||||
"""
|
||||
def __init__(self, user=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.user = user
|
||||
qs = kwargs.get("queryset", None)
|
||||
request_data = kwargs.get("data", None)
|
||||
|
||||
# Pipe the queryset through all needed filters
|
||||
self.selection_filter = SelectionEcoAccountTableFilter(
|
||||
data=request_data,
|
||||
queryset=qs,
|
||||
)
|
||||
self.query_filter = QueryTableFilter(
|
||||
data=request_data,
|
||||
queryset=self.selection_filter.qs,
|
||||
)
|
||||
self.checkbox_filter = CheckboxEcoAccountTableFilter(
|
||||
user=user,
|
||||
data=request_data,
|
||||
queryset=self.query_filter.qs,
|
||||
)
|
||||
# Overwrite the final queryset result
|
||||
self.qs = self.checkbox_filter.qs
|
||||
|
@ -16,11 +16,11 @@ from django.utils.translation import gettext_lazy as _
|
||||
from compensation.filters import CompensationTableFilter, EcoAccountTableFilter
|
||||
from compensation.models import Compensation, EcoAccount
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
|
||||
from konova.utils.tables import BaseTable
|
||||
from konova.utils.tables import BaseTable, TableRenderMixin
|
||||
import django_tables2 as tables
|
||||
|
||||
|
||||
class CompensationTable(BaseTable):
|
||||
class CompensationTable(BaseTable, TableRenderMixin):
|
||||
id = tables.Column(
|
||||
verbose_name=_("Identifier"),
|
||||
orderable=True,
|
||||
@ -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
|
||||
@ -161,7 +162,7 @@ class CompensationTable(BaseTable):
|
||||
return format_html(html)
|
||||
|
||||
|
||||
class EcoAccountTable(BaseTable):
|
||||
class EcoAccountTable(BaseTable, TableRenderMixin):
|
||||
id = tables.Column(
|
||||
verbose_name=_("Identifier"),
|
||||
orderable=True,
|
||||
@ -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
|
||||
|
@ -5,8 +5,6 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 19.08.21
|
||||
|
||||
"""
|
||||
from django.db.models import QuerySet
|
||||
|
||||
from compensation.filters import EcoAccountTableFilter
|
||||
|
||||
|
||||
|
@ -14,12 +14,12 @@ from django.urls import reverse
|
||||
import django_tables2 as tables
|
||||
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
|
||||
from konova.utils.tables import BaseTable
|
||||
from konova.utils.tables import BaseTable, TableRenderMixin
|
||||
from ema.filters import EmaTableFilter
|
||||
from ema.models import Ema
|
||||
|
||||
|
||||
class EmaTable(BaseTable):
|
||||
class EmaTable(BaseTable, TableRenderMixin):
|
||||
"""
|
||||
Since EMA and compensation are basically the same, we can reuse CompensationTableFilter and extend the EMA filter
|
||||
in the future by inheriting.
|
||||
@ -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
|
||||
|
@ -5,119 +5,29 @@ 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.table_filters import AbstractTableFilter, SelectionTableFilter, QueryTableFilter, CheckboxTableFilter
|
||||
|
||||
|
||||
class InterventionTableFilter(django_filters.FilterSet):
|
||||
""" 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
|
||||
class InterventionTableFilter(AbstractTableFilter):
|
||||
def __init__(self, user=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.user = user
|
||||
qs = kwargs.get("queryset", None)
|
||||
request_data = kwargs.get("data", None)
|
||||
|
||||
def _filter_by_keyword(self, queryset, name, value) -> QuerySet:
|
||||
""" Filters queryset depending on value of search bar input
|
||||
# Pipe the queryset through all needed filters
|
||||
self.selection_filter = SelectionTableFilter(
|
||||
data=request_data,
|
||||
queryset=qs,
|
||||
)
|
||||
self.query_filter = QueryTableFilter(
|
||||
data=request_data,
|
||||
queryset=self.selection_filter.qs,
|
||||
)
|
||||
self.checkbox_filter = CheckboxTableFilter(
|
||||
user=user,
|
||||
data=request_data,
|
||||
queryset=self.query_filter.qs,
|
||||
)
|
||||
self.qs = self.checkbox_filter.qs
|
||||
|
||||
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
|
||||
|
@ -14,11 +14,11 @@ from django.utils.translation import gettext_lazy as _
|
||||
from intervention.filters import InterventionTableFilter
|
||||
from intervention.models import Intervention
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT, DEFAULT_DATE_FORMAT
|
||||
from konova.utils.tables import BaseTable
|
||||
from konova.utils.tables import BaseTable, TableRenderMixin
|
||||
import django_tables2 as tables
|
||||
|
||||
|
||||
class InterventionTable(BaseTable):
|
||||
class InterventionTable(BaseTable, TableRenderMixin):
|
||||
id = tables.Column(
|
||||
verbose_name=_("Identifier"),
|
||||
orderable=True,
|
||||
@ -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
|
||||
|
7
konova/filters/__init__.py
Normal file
7
konova/filters/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 12.01.22
|
||||
|
||||
"""
|
406
konova/filters/mixins.py
Normal file
406
konova/filters/mixins.py
Normal file
@ -0,0 +1,406 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 12.01.22
|
||||
|
||||
"""
|
||||
import django_filters
|
||||
from django import forms
|
||||
from django.db.models import QuerySet, Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from dal_select2.widgets import ModelSelect2
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_REGISTRATION_OFFICE_ID
|
||||
from intervention.inputs import DummyFilterInput
|
||||
from konova.models import Parcel, District
|
||||
|
||||
|
||||
class KeywordTableFilterMixin(django_filters.FilterSet):
|
||||
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 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 FileNumberTableFilterMixin(django_filters.FilterSet):
|
||||
rf = django_filters.CharFilter(
|
||||
method="filter_file_number",
|
||||
label=_(""),
|
||||
label_suffix=_(""),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("File number"),
|
||||
"title": _("Search for file number"),
|
||||
"class": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def filter_file_number(self, queryset, name, value) -> QuerySet:
|
||||
queryset = queryset.filter(
|
||||
Q(responsible__registration_file_number__icontains=value) |
|
||||
Q(responsible__conservation_file_number__icontains=value)
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
||||
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"),
|
||||
"class": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
# Parcel gmrkng
|
||||
pg = django_filters.CharFilter(
|
||||
method="filter_gmrkng",
|
||||
label=_(""),
|
||||
label_suffix=_(""),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Parcel gmrkng"),
|
||||
"title": _("Search for parcel gmrkng"),
|
||||
"class": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
# Parcel
|
||||
p = django_filters.CharFilter(
|
||||
method="filter_parcel",
|
||||
label=_(""),
|
||||
label_suffix=_(""),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Parcel"),
|
||||
"title": _("Search for parcel"),
|
||||
"class": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
# 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"),
|
||||
"class": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
# 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": "form-control",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
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(
|
||||
attrs={
|
||||
"class": "form-check-input",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop("user", None)
|
||||
if self.user is None:
|
||||
raise AttributeError("User must be set for further filtering!")
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
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(
|
||||
attrs={
|
||||
"class": "form-check-input",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
|
||||
class RegistrationOfficeTableFilterMixin(django_filters.FilterSet):
|
||||
""" A mixin for AbstractTableFilter
|
||||
|
||||
Specialized on filtering for related registration offices
|
||||
|
||||
"""
|
||||
ro = django_filters.ModelChoiceFilter(
|
||||
method="filter_reg_office",
|
||||
label=_(""),
|
||||
label_suffix=_(""),
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID],
|
||||
),
|
||||
widget=ModelSelect2(
|
||||
url="codes-registration-office-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Registration office"),
|
||||
"title": _("Search for registration office"),
|
||||
"class": "",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def filter_reg_office(self, queryset, name, value):
|
||||
qs = queryset.filter(
|
||||
responsible__registration_office=value
|
||||
)
|
||||
return qs
|
||||
|
||||
|
||||
class ConservationOfficeTableFilterMixin(django_filters.FilterSet):
|
||||
""" A mixin for AbstractTableFilter
|
||||
|
||||
Specialized on filtering for related conservation offices
|
||||
|
||||
"""
|
||||
co = django_filters.ModelChoiceFilter(
|
||||
method="filter_cons_office",
|
||||
label=_(""),
|
||||
label_suffix=_(""),
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID],
|
||||
),
|
||||
widget=ModelSelect2(
|
||||
url="codes-conservation-office-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Conservation office"),
|
||||
"title": _("Search for conservation office"),
|
||||
"class": "",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def filter_cons_office(self, queryset, name, value):
|
||||
qs = queryset.filter(
|
||||
responsible__conservation_office=value
|
||||
)
|
||||
return qs
|
50
konova/filters/table_filters.py
Normal file
50
konova/filters/table_filters.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 12.01.22
|
||||
|
||||
"""
|
||||
import django_filters
|
||||
|
||||
from konova.filters.mixins import RegistrationOfficeTableFilterMixin, ConservationOfficeTableFilterMixin, \
|
||||
KeywordTableFilterMixin, FileNumberTableFilterMixin, GeoReferencedTableFilterMixin, ShareableTableFilterMixin, \
|
||||
RecordableTableFilterMixin
|
||||
|
||||
|
||||
class AbstractTableFilter(django_filters.FilterSet):
|
||||
""" Base TableFilter for all models
|
||||
|
||||
"""
|
||||
selection_filter = None
|
||||
query_filter = None
|
||||
checkbox_filter = None
|
||||
qs = None
|
||||
user = None
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class SelectionTableFilter(RegistrationOfficeTableFilterMixin,
|
||||
ConservationOfficeTableFilterMixin):
|
||||
""" TableFilter holding different filter options for selection related filtering
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class QueryTableFilter(KeywordTableFilterMixin,
|
||||
FileNumberTableFilterMixin,
|
||||
GeoReferencedTableFilterMixin):
|
||||
""" TableFilter holding different filter options for query related filtering
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class CheckboxTableFilter(ShareableTableFilterMixin, RecordableTableFilterMixin):
|
||||
""" TableFilter holding different filter options for checkbox related filtering
|
||||
|
||||
"""
|
||||
pass
|
@ -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]
|
||||
|
@ -404,6 +404,7 @@ class AutocompleteTestCase(BaseViewTestCase):
|
||||
cls.atcmplt_code_comp_process = reverse("codes-process-type-autocomplete")
|
||||
cls.atcmplt_code_comp_reg_off = reverse("codes-registration-office-autocomplete")
|
||||
cls.atcmplt_code_comp_cons_off = reverse("codes-conservation-office-autocomplete")
|
||||
cls.atcmplt_code_share_user = reverse("share-user-autocomplete")
|
||||
|
||||
def _test_views_anonymous_user(self):
|
||||
# ATTENTION: As of the current state of django-autocomplete-light, there is no way to check on authenticated
|
||||
@ -421,6 +422,7 @@ class AutocompleteTestCase(BaseViewTestCase):
|
||||
self.atcmplt_code_comp_process,
|
||||
self.atcmplt_code_comp_reg_off,
|
||||
self.atcmplt_code_comp_cons_off,
|
||||
self.atcmplt_code_share_user,
|
||||
]
|
||||
self.assert_url_fail(client, urls)
|
||||
|
||||
|
@ -5,15 +5,13 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 25.11.20
|
||||
|
||||
"""
|
||||
import uuid
|
||||
|
||||
from django import forms
|
||||
from django.core.paginator import PageNotAnInteger, EmptyPage
|
||||
from django.http import HttpRequest
|
||||
from django.utils.html import format_html
|
||||
import django_tables2 as tables
|
||||
|
||||
from konova.forms import BaseForm
|
||||
from konova.models import BaseObject
|
||||
from konova.settings import PAGE_SIZE_DEFAULT, PAGE_PARAM, RESULTS_PER_PAGE_PARAM, PAGE_SIZE_OPTIONS
|
||||
|
||||
|
||||
@ -31,10 +29,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)
|
||||
@ -149,22 +145,21 @@ class BaseTable(tables.tables.Table):
|
||||
)
|
||||
|
||||
|
||||
class ChoicesColumnForm(BaseForm):
|
||||
select = forms.ChoiceField(
|
||||
choices=[],
|
||||
label="",
|
||||
label_suffix="",
|
||||
widget=forms.Select(
|
||||
attrs={
|
||||
"onchange": "submit();",
|
||||
}
|
||||
)
|
||||
)
|
||||
class TableRenderMixin:
|
||||
""" Holds different render methods for general purposes
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.action_url = kwargs.pop("action_url", None)
|
||||
self.choices = kwargs.pop("choices", [])
|
||||
super().__init__(*args, **kwargs)
|
||||
self.auto_id += "_" + str(uuid.uuid4())
|
||||
if len(self.choices) > 0:
|
||||
self.fields["select"].choices = self.choices
|
||||
"""
|
||||
def render_t(self, value, record: BaseObject):
|
||||
""" Renders a BaseObject title
|
||||
|
||||
Args:
|
||||
value ():
|
||||
record ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
max_length = 75
|
||||
if len(value) > max_length:
|
||||
value = f"{value[:max_length]}..."
|
||||
return value
|
Binary file not shown.
@ -3,23 +3,26 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#: compensation/filters.py:71 compensation/forms/modalForms.py:34
|
||||
#: compensation/filters.py:91 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/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:63 konova/filters.py:64 konova/filters.py:91
|
||||
#: konova/filters.py:92 konova/filters.py:104 konova/filters.py:105
|
||||
#: konova/filters.py:117 konova/filters.py:118 konova/filters.py:130
|
||||
#: konova/filters.py:131 konova/filters.py:144 konova/filters.py:145
|
||||
#: konova/filters.py:280 konova/filters.py:324 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 17:07+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -145,7 +148,7 @@ msgstr "Geprüft"
|
||||
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
|
||||
#: analysis/templates/analysis/reports/includes/intervention/laws.html:20
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:18
|
||||
#: compensation/tables.py:41 compensation/tables.py:181
|
||||
#: compensation/tables.py:41 compensation/tables.py:182
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:77
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:44
|
||||
@ -231,7 +234,7 @@ msgstr "Kompensationsart"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:15
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:29
|
||||
#: compensation/tables.py:84
|
||||
#: compensation/tables.py:85
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:19
|
||||
#: konova/templates/konova/home.html:49 templates/navbars/navbar.html:28
|
||||
msgid "Compensation"
|
||||
@ -276,14 +279,14 @@ msgstr "Typ"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:24
|
||||
#: intervention/forms/modalForms.py:306 intervention/forms/modalForms.py:313
|
||||
#: intervention/tables.py:88
|
||||
#: intervention/tables.py:89
|
||||
#: intervention/templates/intervention/detail/view.html:19
|
||||
#: konova/templates/konova/home.html:11 templates/navbars/navbar.html:22
|
||||
msgid "Intervention"
|
||||
msgstr "Eingriff"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:34
|
||||
#: compensation/tables.py:224
|
||||
#: compensation/tables.py:226
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:19
|
||||
#: intervention/forms/modalForms.py:279 intervention/forms/modalForms.py:286
|
||||
#: konova/templates/konova/home.html:88 templates/navbars/navbar.html:34
|
||||
@ -298,12 +301,12 @@ msgstr "Altfälle"
|
||||
msgid "Before"
|
||||
msgstr "Vor"
|
||||
|
||||
#: compensation/filters.py:70
|
||||
#: compensation/filters.py:90
|
||||
msgid "Show only unrecorded"
|
||||
msgstr "Nur unverzeichnete anzeigen"
|
||||
|
||||
#: compensation/forms/forms.py:32 compensation/tables.py:25
|
||||
#: compensation/tables.py:166 ema/tables.py:28 intervention/forms/forms.py:26
|
||||
#: compensation/tables.py:167 ema/tables.py:28 intervention/forms/forms.py:26
|
||||
#: intervention/tables.py:23
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:30
|
||||
msgid "Identifier"
|
||||
@ -314,7 +317,7 @@ msgid "Generated automatically"
|
||||
msgstr "Automatisch generiert"
|
||||
|
||||
#: compensation/forms/forms.py:44 compensation/tables.py:30
|
||||
#: compensation/tables.py:171
|
||||
#: compensation/tables.py:172
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:28
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
|
||||
@ -633,65 +636,65 @@ msgstr ""
|
||||
"Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen "
|
||||
"wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!"
|
||||
|
||||
#: compensation/tables.py:47 compensation/tables.py:187 ema/tables.py:44
|
||||
#: compensation/tables.py:47 compensation/tables.py:188 ema/tables.py:44
|
||||
#: intervention/tables.py:51
|
||||
msgid "Editable"
|
||||
msgstr "Freigegeben"
|
||||
|
||||
#: compensation/tables.py:53 compensation/tables.py:193 ema/tables.py:50
|
||||
#: compensation/tables.py:53 compensation/tables.py:194 ema/tables.py:50
|
||||
#: intervention/tables.py:57
|
||||
msgid "Last edit"
|
||||
msgstr "Zuletzt bearbeitet"
|
||||
|
||||
#: compensation/tables.py:84 compensation/tables.py:224 ema/tables.py:82
|
||||
#: intervention/tables.py:88
|
||||
#: compensation/tables.py:85 compensation/tables.py:226 ema/tables.py:83
|
||||
#: intervention/tables.py:89
|
||||
msgid "Open {}"
|
||||
msgstr "Öffne {}"
|
||||
|
||||
#: compensation/tables.py:105 intervention/tables.py:107
|
||||
#: compensation/tables.py:106 intervention/tables.py:108
|
||||
msgid "Not checked yet"
|
||||
msgstr "Noch nicht geprüft"
|
||||
|
||||
#: compensation/tables.py:110 intervention/tables.py:112
|
||||
#: compensation/tables.py:111 intervention/tables.py:113
|
||||
msgid "Checked on {} by {}"
|
||||
msgstr "Am {} von {} geprüft worden"
|
||||
|
||||
#: compensation/tables.py:129
|
||||
#: compensation/tables.py:130
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:80
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:56
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:47
|
||||
#: ema/tables.py:101 ema/templates/ema/detail/view.html:38
|
||||
#: intervention/tables.py:131
|
||||
#: ema/tables.py:102 ema/templates/ema/detail/view.html:38
|
||||
#: intervention/tables.py:132
|
||||
#: intervention/templates/intervention/detail/view.html:85
|
||||
msgid "Not recorded yet"
|
||||
msgstr "Noch nicht verzeichnet"
|
||||
|
||||
#: compensation/tables.py:134 compensation/tables.py:262 ema/tables.py:106
|
||||
#: intervention/tables.py:136
|
||||
#: compensation/tables.py:135 compensation/tables.py:264 ema/tables.py:107
|
||||
#: intervention/tables.py:137
|
||||
msgid "Recorded on {} by {}"
|
||||
msgstr "Am {} von {} verzeichnet worden"
|
||||
|
||||
#: compensation/tables.py:158 compensation/tables.py:284 ema/tables.py:129
|
||||
#: intervention/tables.py:159
|
||||
#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:130
|
||||
#: intervention/tables.py:160
|
||||
msgid "Full access granted"
|
||||
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
|
||||
|
||||
#: compensation/tables.py:158 compensation/tables.py:284 ema/tables.py:129
|
||||
#: intervention/tables.py:159
|
||||
#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:130
|
||||
#: intervention/tables.py:160
|
||||
msgid "Access not granted"
|
||||
msgstr "Nicht freigegeben - Datensatz nur lesbar"
|
||||
|
||||
#: compensation/tables.py:176
|
||||
#: compensation/tables.py:177
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:35
|
||||
#: konova/templates/konova/widgets/progressbar.html:3
|
||||
msgid "Available"
|
||||
msgstr "Verfügbar"
|
||||
|
||||
#: compensation/tables.py:202
|
||||
#: compensation/tables.py:203
|
||||
msgid "Eco Accounts"
|
||||
msgstr "Ökokonten"
|
||||
|
||||
#: compensation/tables.py:257
|
||||
#: compensation/tables.py:259
|
||||
msgid "Not recorded yet. Can not be used for deductions, yet."
|
||||
msgstr ""
|
||||
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
|
||||
@ -1177,7 +1180,7 @@ msgstr ""
|
||||
"Maßnahmen aus Ersatzzahlungen, die nach 2015 rechtskräftig wurden, werden "
|
||||
"durch die Stiftung Natur und Umwelt verwaltet."
|
||||
|
||||
#: ema/tables.py:82 templates/navbars/navbar.html:43
|
||||
#: ema/tables.py:83 templates/navbars/navbar.html:43
|
||||
msgid "EMA"
|
||||
msgstr ""
|
||||
|
||||
@ -1197,22 +1200,6 @@ msgstr "EMA {} bearbeitet"
|
||||
msgid "EMA removed"
|
||||
msgstr "EMA entfernt"
|
||||
|
||||
#: intervention/filters.py:25
|
||||
msgid "Show unshared"
|
||||
msgstr "Nicht freigegebene anzeigen"
|
||||
|
||||
#: intervention/filters.py:39
|
||||
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"
|
||||
@ -1382,11 +1369,11 @@ msgstr ""
|
||||
msgid "Revocation"
|
||||
msgstr "Widerspruch"
|
||||
|
||||
#: intervention/tables.py:176
|
||||
#: intervention/tables.py:177
|
||||
msgid "No revocation"
|
||||
msgstr "Kein Widerspruch"
|
||||
|
||||
#: intervention/tables.py:182
|
||||
#: intervention/tables.py:183
|
||||
msgid "Revocation from {}, added on {} by {}"
|
||||
msgstr "Widerspruch vom {}, am {} von {} hinzugefügt"
|
||||
|
||||
@ -1521,6 +1508,62 @@ msgstr ""
|
||||
"somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. "
|
||||
"Kontaktieren Sie bitte einen Administrator. +++"
|
||||
|
||||
#: konova/filters.py:67
|
||||
msgid "File number"
|
||||
msgstr "Aktenzeichen"
|
||||
|
||||
#: konova/filters.py:68
|
||||
msgid "Search for file number"
|
||||
msgstr "Nach Aktenzeichen suchen"
|
||||
|
||||
#: konova/filters.py:95
|
||||
msgid "District"
|
||||
msgstr "Kreis"
|
||||
|
||||
#: konova/filters.py:96
|
||||
msgid "Search for district"
|
||||
msgstr "Nach Kreis suchen"
|
||||
|
||||
#: konova/filters.py:108
|
||||
msgid "Parcel gmrkng"
|
||||
msgstr "Gemarkung"
|
||||
|
||||
#: konova/filters.py:109
|
||||
msgid "Search for parcel gmrkng"
|
||||
msgstr "Nach Gemarkung suchen"
|
||||
|
||||
#: konova/filters.py:121 konova/templates/konova/includes/parcels.html:18
|
||||
msgid "Parcel"
|
||||
msgstr "Flur"
|
||||
|
||||
#: konova/filters.py:122
|
||||
msgid "Search for parcel"
|
||||
msgstr "Nach Flur suchen"
|
||||
|
||||
#: konova/filters.py:134 konova/templates/konova/includes/parcels.html:19
|
||||
msgid "Parcel counter"
|
||||
msgstr "Flurstückzähler"
|
||||
|
||||
#: konova/filters.py:135
|
||||
msgid "Search for parcel counter"
|
||||
msgstr "Nach Flurstückzähler suchen"
|
||||
|
||||
#: konova/filters.py:148 konova/templates/konova/includes/parcels.html:20
|
||||
msgid "Parcel number"
|
||||
msgstr "Flurstücknenner"
|
||||
|
||||
#: konova/filters.py:149
|
||||
msgid "Search for parcel number"
|
||||
msgstr "Nach Flurstücknenner suchen"
|
||||
|
||||
#: konova/filters.py:279
|
||||
msgid "Show unshared"
|
||||
msgstr "Nicht freigegebene anzeigen"
|
||||
|
||||
#: konova/filters.py:323
|
||||
msgid "Show recorded"
|
||||
msgstr "Verzeichnete anzeigen"
|
||||
|
||||
#: konova/forms.py:37 templates/form/collapsable/form.html:62
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
@ -1687,18 +1730,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"
|
||||
@ -1899,11 +1930,11 @@ msgstr "Starte Suche"
|
||||
msgid "Results per page"
|
||||
msgstr "Treffer pro Seite"
|
||||
|
||||
#: templates/generic_index.html:82 templates/generic_index.html:88
|
||||
#: templates/generic_index.html:82 templates/generic_index.html:99
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_index.html:90
|
||||
#: templates/generic_index.html:101
|
||||
msgid "Apply filter"
|
||||
msgstr "Filter anwenden"
|
||||
|
||||
|
5
templates/filter/checkbox_filter.html
Normal file
5
templates/filter/checkbox_filter.html
Normal file
@ -0,0 +1,5 @@
|
||||
{% for field in form %}
|
||||
<div class="form-check form-check-inline">
|
||||
{{field}} <label class="form-check-label" for="id_{{field.name}}">{{field.label}}</label>
|
||||
</div>
|
||||
{% endfor %}
|
10
templates/filter/query_filter.html
Normal file
10
templates/filter/query_filter.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="form-row align-items-center">
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div class="col-auto">
|
||||
{{field}}
|
||||
</div>
|
||||
{% else %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
@ -3,6 +3,16 @@
|
||||
{% load django_tables2 %}
|
||||
{% load i18n static fontawesome_5 %}
|
||||
|
||||
{% block head %}
|
||||
{% comment %}
|
||||
dal documentation (django-autocomplete-light) states using form.media for adding needed scripts.
|
||||
This does not work properly with modal forms, as the scripts are not loaded properly inside the modal.
|
||||
Therefore the script linkages from form.media have been extracted and put inside dal/scripts.html to ensure
|
||||
these scripts are loaded when needed.
|
||||
{% endcomment %}
|
||||
{% include 'dal/scripts.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="col-md">
|
||||
{% if table.title %}
|
||||
@ -41,7 +51,7 @@
|
||||
<div class="row my-1">
|
||||
<div class="col-sm-12 col-md-8 col-lg-6">
|
||||
<div class="input-group">
|
||||
<input id="id_{{table.filter.filters.q.field_name}}" name="{{table.filter.filters.q.field_name}}" type="text" class="form-control" aria-label="{% trans 'Search for keywords' %}" placeholder="{% trans 'Search' %}" value="{{ request.GET.q }}">
|
||||
<input id="id_{{table.filter.query_filter.filters.q.field_name}}" name="{{table.filter.query_filter.filters.q.field_name}}" type="text" class="form-control" aria-label="{% trans 'Search for keywords' %}" placeholder="{% trans 'Search' %}" value="{{ request.GET.q }}">
|
||||
<div class="input-group-append" title="{% trans 'Start search' %}">
|
||||
<button type="submit" class="btn btn-default input-group-text">
|
||||
<span class="">
|
||||
@ -82,11 +92,32 @@
|
||||
</div>
|
||||
<div id="filter" class="collapse" aria-labelledby="filterHeader">
|
||||
<div class="card-body">
|
||||
{{ table.filter.form.as_p }}
|
||||
<button class="btn btn-default" title="{% trans 'Filter' %}">
|
||||
{% fa5_icon 'filter' %}
|
||||
{% trans 'Apply filter' %}
|
||||
</button>
|
||||
<div class="">
|
||||
<div class="">
|
||||
{% with table.filter.selection_filter.form as form %}
|
||||
{% include 'filter/query_filter.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<hr>
|
||||
<div class="mt-3">
|
||||
{% with table.filter.query_filter.form as form %}
|
||||
{% include 'filter/query_filter.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<hr>
|
||||
<div class="mt-3">
|
||||
{% with table.filter.checkbox_filter.form as form %}
|
||||
{% include 'filter/checkbox_filter.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<hr>
|
||||
<div class="mt-3">
|
||||
<button class="btn btn-default" title="{% trans 'Filter' %}">
|
||||
{% fa5_icon 'filter' %}
|
||||
{% trans 'Apply filter' %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user