Skip to content

Commit

Permalink
Merge pull request #3813 from GeotrekCE/refactor_filters
Browse files Browse the repository at this point in the history
Refactor filters
  • Loading branch information
submarcos authored Oct 27, 2023
2 parents 26d1e8e + 6420a7b commit 6cf5f1f
Show file tree
Hide file tree
Showing 16 changed files with 56 additions and 107 deletions.
21 changes: 2 additions & 19 deletions geotrek/cirkwi/filters.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
from django_filters import ModelMultipleChoiceFilter, FilterSet
from django_filters.fields import ModelChoiceField
from django_filters import FilterSet
from geotrek.authent.models import Structure
from geotrek.common.filters import ComaSeparatedMultipleModelChoiceFilter
from geotrek.common.models import TargetPortal
from geotrek.trekking.models import POI, Trek
from django.forms import ValidationError


class ComaSeparatedMultipleModelChoiceField(ModelChoiceField):
def to_python(self, value):
if value in self.empty_values:
return None
try:
key = self.to_field_name or 'pk'
value = self.queryset.filter(**{f'{key}__in': value.split(',')})
except (ValueError, TypeError):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return value


class ComaSeparatedMultipleModelChoiceFilter(ModelMultipleChoiceFilter):
field_class = ComaSeparatedMultipleModelChoiceField


class CirkwiPOIFilterSet(FilterSet):
Expand Down
7 changes: 0 additions & 7 deletions geotrek/common/fields.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
from django_filters import ModelMultipleChoiceFilter, RangeFilter
from mapentity.filters import MapEntityFilterSet

from geotrek.common.filters.fields import ComaSeparatedMultipleModelChoiceField, OneLineRangeField
from geotrek.common.models import HDViewPoint

from .fields import OneLineRangeField

class ComaSeparatedMultipleModelChoiceFilter(ModelMultipleChoiceFilter):
field_class = ComaSeparatedMultipleModelChoiceField


class OptionalRangeFilter(RangeFilter):
Expand Down
20 changes: 20 additions & 0 deletions geotrek/common/filters/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.core.exceptions import ValidationError
from django_filters.fields import ModelChoiceField, RangeField

from geotrek.common.widgets import OneLineRangeWidget


class ComaSeparatedMultipleModelChoiceField(ModelChoiceField):
def to_python(self, value):
if value in self.empty_values:
return None
try:
key = self.to_field_name or 'pk'
value = self.queryset.filter(**{f'{key}__in': value.split(',')})
except (ValueError, TypeError):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return value


class OneLineRangeField(RangeField):
widget = OneLineRangeWidget(attrs={'class': 'minmax-field'})
Empty file.
12 changes: 2 additions & 10 deletions geotrek/core/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class PathFilterSet(AltimetryAllGeometriesFilterSet, ZoningFilterSet, StructureR
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Path.objects.provider_choices()
)
networks = ModelMultipleChoiceFilter(queryset=Network.objects.all().select_related("structure"))
usages = ModelMultipleChoiceFilter(queryset=Usage.objects.all().select_related("structure"))
Expand All @@ -114,10 +114,6 @@ class Meta(StructureRelatedFilterSet.Meta):
fields = StructureRelatedFilterSet.Meta.fields + \
['valid', 'networks', 'usages', 'comfort', 'stake', 'draft', 'provider']

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Path.objects.provider_choices()


class TrailFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilterSet, ZoningFilterSet, StructureRelatedFilterSet):
"""Trail filter set"""
Expand All @@ -134,18 +130,14 @@ class TrailFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilterSet, Zo
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Trail.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
model = Trail
fields = StructureRelatedFilterSet.Meta.fields + \
['name', 'category', 'departure', 'arrival', 'certification_labels', 'comments', 'provider']

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Trail.objects.provider_choices()


class TopologyFilterTrail(TopologyFilter):
queryset = Trail.objects.existing()
Expand Down
16 changes: 7 additions & 9 deletions geotrek/core/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,7 @@ def test_draft_path_layer_cache(self):
obj = self.modelfactory(draft=False)
self.modelfactory(draft=True)

# There are 7 queries to get layer without drafts
with self.assertNumQueries(5):
with self.assertNumQueries(4):
response = self.client.get(obj.get_layer_url(), {"_no_draft": "true"})
self.assertEqual(len(response.json()['features']), 1)

Expand Down Expand Up @@ -599,7 +598,7 @@ def test_draft_path_layer_cache(self):
self.modelfactory(draft=False)

# Cache was updated, the path was not a draft : we get 7 queries
with self.assertNumQueries(5):
with self.assertNumQueries(4):
self.client.get(obj.get_layer_url(), {"_no_draft": "true"})

def test_path_layer_cache(self):
Expand All @@ -612,8 +611,7 @@ def test_path_layer_cache(self):
obj = self.modelfactory(draft=False)
self.modelfactory(draft=True)

# There are 7 queries to get layer without drafts
with self.assertNumQueries(5):
with self.assertNumQueries(4):
response = self.client.get(obj.get_layer_url())
self.assertEqual(len(response.json()['features']), 2)

Expand All @@ -636,13 +634,13 @@ def test_path_layer_cache(self):
self.modelfactory(draft=True)

# Cache is updated when we add a draft path
with self.assertNumQueries(5):
with self.assertNumQueries(4):
self.client.get(obj.get_layer_url())

self.modelfactory(draft=False)

# Cache is updated when we add a path
with self.assertNumQueries(5):
with self.assertNumQueries(4):
self.client.get(obj.get_layer_url())


Expand Down Expand Up @@ -695,7 +693,7 @@ def test_denormalized_path_trails(self):
PathFactory.create_batch(size=50)
TrailFactory.create_batch(size=50)
self.login()
with self.assertNumQueries(6):
with self.assertNumQueries(5):
self.client.get(reverse('core:path-drf-list', kwargs={'format': 'datatables'}))


Expand Down Expand Up @@ -799,7 +797,7 @@ def test_add_trail_from_existing_topology(self):

def test_perfs_export_csv(self):
self.modelfactory.create()
with self.assertNumQueries(14):
with self.assertNumQueries(11):
self.client.get(self.model.get_format_list_url() + '?format=csv')


Expand Down
12 changes: 3 additions & 9 deletions geotrek/infrastructure/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
class InfrastructureFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilterSet, ZoningFilterSet, StructureRelatedFilterSet):
name = CharFilter(label=_('Name'), lookup_expr='icontains')
description = CharFilter(label=_('Description'), lookup_expr='icontains')
implantation_year = MultipleChoiceFilter(choices=(('', '---------'),))
implantation_year = MultipleChoiceFilter(choices=lambda: Infrastructure.objects.implantation_year_choices())
intervention_year = MultipleChoiceFilter(label=_("Intervention year"), method='filter_intervention_year',
choices=(('', '---------'),))
choices=lambda: Intervention.objects.year_choices())
category = MultipleChoiceFilter(label=_("Category"), field_name='type__type',
choices=INFRASTRUCTURE_TYPES)
trail = TopologyFilterTrail(label=_('Trail'), required=False)
Expand All @@ -24,7 +24,7 @@ class InfrastructureFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilt
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Infrastructure.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand All @@ -39,9 +39,3 @@ def filter_intervention_year(self, qs, name, value):
interventions = Intervention.objects.filter(target_type=infrastructure_ct, date__year__in=value) \
.values_list('target_id', flat=True)
return qs.filter(id__in=interventions).distinct()

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['implantation_year'].choices = Infrastructure.objects.implantation_year_choices()
self.form.fields['provider'].choices = Infrastructure.objects.provider_choices()
self.form.fields['intervention_year'].choices = Intervention.objects.year_choices()
4 changes: 2 additions & 2 deletions geotrek/maintenance/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class InterventionFilterSet(AltimetryInterventionFilterSet, ZoningFilterSet, Str
ON_CHOICES += (('course', _("Outdoor Course")), ('site', _("Outdoor Site")),)

bbox = PolygonTopologyFilter(lookup_expr='intersects')
year = MultipleChoiceFilter(choices=(('', '---------'),),
year = MultipleChoiceFilter(choices=lambda: Intervention.objects.year_choices(),
field_name='date', lookup_expr='year', label=_("Year"))
on = ChoiceFilter(field_name='target_type__model', choices=ON_CHOICES, label=_("On"), empty_label=_("On"))
area_type = InterventionIntersectionFilterRestrictedAreaType(label=_('Restricted area type'), required=False,
Expand All @@ -155,7 +155,7 @@ class ProjectFilterSet(StructureRelatedFilterSet):
bbox = PythonPolygonFilter(field_name='geom')
year = MultipleChoiceFilter(
label=_("Year of activity"), method='filter_year',
choices=(('', '---------'),)
choices=lambda: Project.objects.year_choices()
)
city = ProjectIntersectionFilterCity(label=_('City'), lookup_expr='intersects', required=False)
district = ProjectIntersectionFilterDistrict(label=_('District'), lookup_expr='intersects', required=False)
Expand Down
12 changes: 2 additions & 10 deletions geotrek/outdoor/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SiteFilterSet(ZoningFilterSet, StructureRelatedFilterSet):
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Site.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand All @@ -27,10 +27,6 @@ class Meta(StructureRelatedFilterSet.Meta):
'web_links', 'type', 'orientation', 'wind', 'provider'
]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Site.objects.provider_choices()

def filter_orientation(self, qs, name, values):
q = Q()
for value in values:
Expand Down Expand Up @@ -62,7 +58,7 @@ class CourseFilterSet(ZoningFilterSet, StructureRelatedFilterSet):
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Course.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand All @@ -73,10 +69,6 @@ class Meta(StructureRelatedFilterSet.Meta):
'height', 'provider'
]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Course.objects.provider_choices()

def filter_orientation(self, qs, name, values):
q = Q()
for value in values:
Expand Down
2 changes: 1 addition & 1 deletion geotrek/sensitivity/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SensitiveAreaFilterSet(StructureRelatedFilterSet):
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: SensitiveArea.objects.provider_choices()
)

def __init__(self, *args, **kwargs):
Expand Down
12 changes: 3 additions & 9 deletions geotrek/signage/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ def filter(self, qs, value):
class SignageFilterSet(AltimetryPointFilterSet, ValidTopologyFilterSet, ZoningFilterSet, StructureRelatedFilterSet):
name = CharFilter(label=_('Name'), lookup_expr='icontains')
description = CharFilter(label=_('Description'), lookup_expr='icontains')
implantation_year = MultipleChoiceFilter(choices=(('', '---------'),))
implantation_year = MultipleChoiceFilter(choices=lambda: Signage.objects.implantation_year_choices())
intervention_year = MultipleChoiceFilter(label=_("Intervention year"), method='filter_intervention_year',
choices=(('', '---------'),))
choices=lambda: Intervention.objects.year_choices())
trail = TopologyFilterTrail(label=_('Trail'), required=False)
provider = ChoiceFilter(
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Signage.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand All @@ -44,12 +44,6 @@ class Meta(StructureRelatedFilterSet.Meta):
'published', 'code', 'printed_elevation', 'manager',
'sealing', 'access', 'provider']

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['implantation_year'].choices = Signage.objects.implantation_year_choices()
self.form.fields['provider'].choices = Signage.objects.provider_choices()
self.form.fields['intervention_year'].choices = Intervention.objects.year_choices()

def filter_intervention_year(self, qs, name, value):
signage_ct = ContentType.objects.get_for_model(Signage)
interventions = Intervention.objects.filter(target_type=signage_ct, date__year__in=value) \
Expand Down
12 changes: 2 additions & 10 deletions geotrek/tourism/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,9 @@ class TouristicContentFilterSet(ZoningFilterSet, StructureRelatedFilterSet):
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: TouristicContent.objects.provider_choices()
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = TouristicContent.objects.provider_choices()

class Meta(StructureRelatedFilterSet.Meta):
model = TouristicContent
fields = StructureRelatedFilterSet.Meta.fields + [
Expand Down Expand Up @@ -73,13 +69,9 @@ class TouristicEventFilterSet(ZoningFilterSet, StructureRelatedFilterSet):
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: TouristicEvent.objects.provider_choices()
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = TouristicEvent.objects.provider_choices()

class Meta(StructureRelatedFilterSet.Meta):
model = TouristicEvent
fields = StructureRelatedFilterSet.Meta.fields + [
Expand Down
2 changes: 1 addition & 1 deletion geotrek/tourism/tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def test_csv_participants_count(self):
total_count = sum(map(attrgetter('count'), counts))
self.assertEqual(event.participants_total, total_count)
self.assertEqual(event.participants_total_verbose_name, "Number of participants")
with self.assertNumQueries(18):
with self.assertNumQueries(15):
response = self.client.get(event.get_format_list_url())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Type'), 'text/csv')
Expand Down
18 changes: 3 additions & 15 deletions geotrek/trekking/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TrekFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilterSet, Zon
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Trek.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand All @@ -24,10 +24,6 @@ class Meta(StructureRelatedFilterSet.Meta):
'source', 'portal', 'reservation_system', 'provider'
]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Trek.objects.provider_choices()


class POITrekFilter(TopologyFilter):
queryset = Trek.objects.existing()
Expand All @@ -39,13 +35,9 @@ class POIFilterSet(AltimetryPointFilterSet, ValidTopologyFilterSet, ZoningFilter
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: POI.objects.provider_choices()
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = POI.objects.provider_choices()

class Meta(StructureRelatedFilterSet.Meta):
model = POI
fields = StructureRelatedFilterSet.Meta.fields + [
Expand All @@ -58,13 +50,9 @@ class ServiceFilterSet(AltimetryPointFilterSet, ValidTopologyFilterSet, ZoningFi
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=(('', '---------'),)
choices=lambda: Service.objects.provider_choices()
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['provider'].choices = Service.objects.provider_choices()

class Meta(StructureRelatedFilterSet.Meta):
model = Service
fields = StructureRelatedFilterSet.Meta.fields + ['type', 'provider']
Loading

0 comments on commit 6cf5f1f

Please sign in to comment.