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
						31b3428146
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user