diff --git a/Makefile b/Makefile index b9f94cafd6..894f359957 100644 --- a/Makefile +++ b/Makefile @@ -107,10 +107,10 @@ coverage: rm ./var/.coverage* test: - $(docker_compose) run -e ENV=tests --rm web ./manage.py test --shuffle --noinput --parallel + $(docker_compose) run -e ENV=tests --rm web ./manage.py test $(test_name) --shuffle --noinput --parallel test_nds: - $(docker_compose) run -e ENV=tests_nds --rm web ./manage.py test --shuffle --noinput --parallel + $(docker_compose) run -e ENV=tests_nds --rm web ./manage.py test $(test_name) --shuffle --noinput --parallel tests: test test_nds diff --git a/cypress/integration/nav_create_signage.js b/cypress/integration/nav_create_signage.js index 410e8e25b9..300724cf6f 100644 --- a/cypress/integration/nav_create_signage.js +++ b/cypress/integration/nav_create_signage.js @@ -34,7 +34,7 @@ describe('Create signage', () => { cy.get("input[name='name_en']").type('Signage number 1') cy.get("a[href='#name_fr']").click() cy.get("input[name='name_fr']").type('Signalétique numéro 1') - cy.get("select[id='id_type']").select("Service") + cy.get("select[id='id_type']").select("Service", { force: true }) cy.get('#save_changes').click() cy.url().should('not.include', '/signage/add/') }) diff --git a/cypress/integration/nav_create_trek.js b/cypress/integration/nav_create_trek.js index ad4007872d..f4aacc3986 100644 --- a/cypress/integration/nav_create_trek.js +++ b/cypress/integration/nav_create_trek.js @@ -38,9 +38,9 @@ describe('Create trek', () => { cy.get("a[href='#arrival_fr']").click(); cy.get("input[id='id_arrival_fr']").type('Arrivée'); cy.get("input[id='id_duration']").type('100'); - cy.get("select[id='id_practice']").select("Cycling"); - cy.get("select[id='id_difficulty']").select("Very hard"); - cy.get("select[id='id_route']").select("Loop"); + cy.get("select[id='id_practice']").select("Cycling", { force: true }); + cy.get("select[id='id_difficulty']").select("Very hard", { force: true }); + cy.get("select[id='id_route']").select("Loop", { force: true }); cy.setTinyMceContent('id_access_en', 'Access number 1');; cy.setTinyMceContent('id_description_teaser_en', 'Description teaser number 1'); cy.setTinyMceContent('id_ambiance_en', 'Ambiance number 1'); diff --git a/cypress/integration/nav_reports_workflow.js b/cypress/integration/nav_reports_workflow.js index d38cb6cead..e96a1acc6a 100644 --- a/cypress/integration/nav_reports_workflow.js +++ b/cypress/integration/nav_reports_workflow.js @@ -23,22 +23,22 @@ describe('Nav reports workflow', () => { cy.get("#id_message_administrators").should("not.be.visible") cy.get("#id_message_supervisor").should("not.be.visible") // Change selected status to resolved - cy.get("#id_status").select("3") + cy.get("#id_status").select("3", { force: true }) // Can use selectors for sentinel messages cy.get("#id_message_sentinel_predefined").should("be.visible") cy.get("#id_message_sentinel").should("be.visible") cy.get("#id_message_administrators").should("be.visible") cy.get("#id_message_supervisor").should("not.be.visible") // Select a predefined email - cy.get("#id_message_sentinel_predefined").select("1") + cy.get("#id_message_sentinel_predefined").select("1", { force: true }) cy.get("#id_message_sentinel").should("have.value", "Pris en charge par Comm des Comm des Arbres Binaires le 17/05/2022") cy.get("#id_message_administrators").should("have.value", "Pris en charge par Comm des Comm des Arbres Binaires le 17/05/2022") // Remove predefined email - cy.get("#id_message_sentinel_predefined").select("") + cy.get("#id_message_sentinel_predefined").select("", { force: true }) cy.get("#id_message_sentinel").should("have.value", "") cy.get("#id_message_administrators").should("have.value", "") // Change selected status back to initial one - cy.get("#id_status").select("1") + cy.get("#id_status").select("1", { force: true }) // Cannot use selectors for sentinel and supervisor messages anymore cy.get("#id_message_sentinel_predefined").should("not.be.visible") cy.get("#id_message_sentinel").should("not.be.visible") @@ -55,9 +55,9 @@ describe('Nav reports workflow', () => { cy.get("#id_message_administrators").should("not.be.visible") cy.get("#id_message_supervisor").should("not.be.visible") // Change selected status to waiting - cy.get("#id_status").select("4") + cy.get("#id_status").select("4", { force: true }) // Select an assigned user - cy.get("#id_current_user").select("5") + cy.get("#id_current_user").select("5", { force: true }) // Can use selectors for sentinel and supervisor messages cy.get("#id_message_sentinel_predefined").scrollIntoView().should("be.visible") cy.get("#id_message_sentinel").scrollIntoView().should("be.visible") @@ -65,27 +65,27 @@ describe('Nav reports workflow', () => { cy.get("#id_message_supervisor").scrollIntoView().should("be.visible") cy.get("#modelfields").scrollTo('bottom').get("#id_message_supervisor").should("be.visible") // Select a predefined email - cy.get("#id_message_sentinel_predefined").select("2") + cy.get("#id_message_sentinel_predefined").select("2", { force: true }) cy.get("#id_message_sentinel").should("have.value", "Faire attention a la marche") cy.get("#id_message_administrators").should("have.value", "Faire attention a la marche") cy.get("#id_message_supervisor").should("have.value", "") // Select another predefined email - cy.get("#id_message_sentinel_predefined").select("3") + cy.get("#id_message_sentinel_predefined").select("3", { force: true }) cy.get("#id_message_sentinel").should("have.value", "Ce probleme n'en sera bientot plus un") cy.get("#id_message_administrators").should("have.value", "Ce probleme n'en sera bientot plus un") // Select another assigned user - cy.get("#id_current_user").select("1") + cy.get("#id_current_user").select("1", { force: true }) // Can use selectors for sentinel and supervisor messages cy.get("#id_message_sentinel_predefined").scrollIntoView().should("be.visible") cy.get("#id_message_sentinel").scrollIntoView().should("be.visible") cy.get("#id_message_administrators").scrollIntoView().should("be.visible") cy.get("#modelfields").scrollTo('bottom').get("#id_message_supervisor").should("be.visible") // Remove predefined email - cy.get("#id_message_sentinel_predefined").select("") + cy.get("#id_message_sentinel_predefined").select("", { force: true }) cy.get("#id_message_sentinel").should("have.value", "") cy.get("#id_message_administrators").should("have.value", "") // Change status back - cy.get("#id_status").select("2") + cy.get("#id_status").select("2", { force: true }) // Cannot use selectors for sentinel and supervisor messages anymore cy.get("#id_message_sentinel_predefined").should("not.be.visible") cy.get("#id_message_sentinel").should("not.be.visible") diff --git a/docker/Dockerfile b/docker/Dockerfile index 901623c8a4..d803dcd6c6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -78,12 +78,13 @@ FROM base AS build USER root -RUN apt-get update -qq && apt-get install -y -qq \ - git \ - build-essential \ - graphviz \ - libpq-dev &&\ - apt-get clean all && rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apt/* +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update -qq && apt-get install -y -qq \ + git \ + build-essential \ + graphviz \ + libpq-dev USER geotrek diff --git a/geotrek/altimetry/filters.py b/geotrek/altimetry/filters.py index f047a8a9b1..c10178412b 100644 --- a/geotrek/altimetry/filters.py +++ b/geotrek/altimetry/filters.py @@ -1,10 +1,10 @@ from django.utils.translation import gettext_lazy as _ -from django_filters import FilterSet +from mapentity.filters import MapEntityFilterSet from geotrek.common.filters import OptionalRangeFilter -class AltimetryPointFilterSet(FilterSet): +class AltimetryPointFilterSet(MapEntityFilterSet): elevation = OptionalRangeFilter(label=_("elevation"), method="filter_elevation") def filter_elevation(self, qs, name, value): diff --git a/geotrek/api/v2/serializers.py b/geotrek/api/v2/serializers.py index 51fea8ec00..2278d3f58b 100644 --- a/geotrek/api/v2/serializers.py +++ b/geotrek/api/v2/serializers.py @@ -1293,7 +1293,10 @@ def get_elevation(self, obj): return obj.species.radius def get_species_id(self, obj): - if obj.species.category == sensitivity_models.Species.SPECIES: + if ( + obj.species.category + == sensitivity_models.Species.CategoryChoices.SPECIES + ): return obj.species_id return None @@ -1346,7 +1349,8 @@ class BubbleSensitiveAreaSerializer(SensitiveAreaSerializer): def get_radius(self, obj): if ( - obj.species.category == sensitivity_models.Species.SPECIES + obj.species.category + == sensitivity_models.Species.CategoryChoices.SPECIES and obj.geom.geom_typeid == 0 ): return obj.species.radius diff --git a/geotrek/common/filters/fields.py b/geotrek/common/filters/fields.py index 7a2d5cf337..9fe0df1b6b 100644 --- a/geotrek/common/filters/fields.py +++ b/geotrek/common/filters/fields.py @@ -19,4 +19,6 @@ def to_python(self, value): class OneLineRangeField(RangeField): - widget = OneLineRangeWidget(attrs={"class": "minmax-field"}) + widget = OneLineRangeWidget( + attrs={"class": "minmax-field form-control form-control-sm"} + ) diff --git a/geotrek/common/mixins/models.py b/geotrek/common/mixins/models.py index c27e2ffb4e..1f2b3132be 100644 --- a/geotrek/common/mixins/models.py +++ b/geotrek/common/mixins/models.py @@ -5,9 +5,10 @@ import uuid from django.conf import settings +from django.contrib.gis.db import models +from django.contrib.gis.db.models.functions import Envelope, Transform from django.core.files.storage import default_storage from django.core.mail import mail_managers -from django.db import models from django.db.models import Count, Max from django.template import Context, Template from django.template.defaultfilters import slugify @@ -512,3 +513,18 @@ def get_eid(self): "{% load i18n %} {% trans 'None' %}" ) return mark_safe(tmpl.render(Context({}))) + + +class BBoxMixin(models.Model): + envelope = models.GeneratedField( + expression=Envelope(Transform("geom", settings.API_SRID)), + db_persist=True, + output_field=models.GeometryField(), + ) + + @property + def bbox(self): + return self.envelope.extent + + class Meta: + abstract = True diff --git a/geotrek/common/static/common/style.css b/geotrek/common/static/common/style.css index 5be5a19fc2..308a063944 100644 --- a/geotrek/common/static/common/style.css +++ b/geotrek/common/static/common/style.css @@ -1,5 +1,12 @@ #mainfilter input.minmax-field { width: calc(60% - 1.9rem); + border-radius: 1px !important; + +} + +#mainfilter .form-row { + margin-right: 0 !important; + margin-left: 0 !important; } .caption-detail { diff --git a/geotrek/common/templates/common/range_widget.html b/geotrek/common/templates/common/range_widget.html index 14bffc9503..0c194e87d8 100644 --- a/geotrek/common/templates/common/range_widget.html +++ b/geotrek/common/templates/common/range_widget.html @@ -1 +1 @@ -{% for widget in widget.subwidgets %}{% include widget.template_name %}{% if forloop.first %}- {% endif %}{% endfor %} +
{% for widget in widget.subwidgets %}{% include widget.template_name %}{% if forloop.first %} - {% endif %}{% endfor %}
diff --git a/geotrek/core/filters.py b/geotrek/core/filters.py index 26c3ee1c85..fcb98196a0 100644 --- a/geotrek/core/filters.py +++ b/geotrek/core/filters.py @@ -1,9 +1,10 @@ +from dal import autocomplete from django.conf import settings from django.db.models import Count, F, Q +from django.forms import widgets from django.utils.translation import gettext_lazy as _ from django_filters import ( BooleanFilter, - CharFilter, FilterSet, ModelMultipleChoiceFilter, ) @@ -27,10 +28,18 @@ class ValidTopologyFilterSet(FilterSet): if settings.TREKKING_TOPOLOGY_ENABLED: is_valid_topology = BooleanFilter( - label=_("Valid topology"), method="filter_valid_topology" + label=_("Valid topology"), + method="filter_valid_topology", + widget=widgets.NullBooleanSelect( + attrs={"class": "form-control form-control-sm"} + ), ) is_valid_geometry = BooleanFilter( - label=_("Valid geometry"), method="filter_valid_geometry" + label=_("Valid geometry"), + method="filter_valid_geometry", + widget=widgets.NullBooleanSelect( + attrs={"class": "form-control form-control-sm"} + ), ) def filter_valid_topology(self, qs, name, value): @@ -124,26 +133,30 @@ def _topology_filter(self, qs, edges): class PathFilterSet( AltimetryAllGeometriesFilterSet, ZoningFilterSet, StructureRelatedFilterSet ): - name = CharFilter(label=_("Name"), lookup_expr="icontains") - comments = CharFilter(label=_("Comments"), lookup_expr="icontains") provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(path__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) networks = ModelMultipleChoiceFilter( - queryset=Network.objects.all().select_related("structure") + queryset=Network.objects.all().select_related("structure"), + widget=autocomplete.Select2Multiple(), ) usages = ModelMultipleChoiceFilter( - queryset=Usage.objects.all().select_related("structure") + queryset=Usage.objects.all().select_related("structure"), + widget=autocomplete.Select2Multiple(), ) comfort = ModelMultipleChoiceFilter( - queryset=Comfort.objects.all().select_related("structure") + queryset=Comfort.objects.all().select_related("structure"), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): model = Path fields = [ *StructureRelatedFilterSet.Meta.fields, + "name", + "comments", "valid", "networks", "usages", @@ -160,20 +173,16 @@ class TrailFilterSet( ZoningFilterSet, StructureRelatedFilterSet, ): - """Trail filter set""" - - name = CharFilter(label=_("Name"), lookup_expr="icontains") - departure = CharFilter(label=_("Departure"), lookup_expr="icontains") - arrival = CharFilter(label=_("Arrival"), lookup_expr="icontains") - comments = CharFilter(label=_("Comments"), lookup_expr="icontains") certification_labels = ModelMultipleChoiceFilter( field_name="certifications__certification_label", label=_("Certification labels"), queryset=CertificationLabel.objects.all(), + widget=autocomplete.Select2Multiple(), ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(trail__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): @@ -197,5 +206,11 @@ class TopologyFilterTrail(TopologyFilter): if settings.TRAIL_MODEL_ENABLED: for filterset in (PathFilterSet, InterventionFilterSet, ProjectFilterSet): filterset.add_filters( - {"trail": TopologyFilterTrail(label=_("Trail"), required=False)} + { + "trail": TopologyFilterTrail( + label=_("Trail"), + required=False, + widget=autocomplete.Select2Multiple(), + ) + } ) diff --git a/geotrek/core/locale/de/LC_MESSAGES/django.po b/geotrek/core/locale/de/LC_MESSAGES/django.po index 015ca41757..80f6a9c09d 100644 --- a/geotrek/core/locale/de/LC_MESSAGES/django.po +++ b/geotrek/core/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" @@ -43,21 +43,9 @@ msgstr "" msgid "Valid geometry" msgstr "" -msgid "Name" -msgstr "" - -msgid "Comments" -msgstr "" - msgid "Provider" msgstr "" -msgid "Departure" -msgstr "" - -msgid "Arrival" -msgstr "" - msgid "Certification labels" msgstr "" @@ -115,15 +103,27 @@ msgstr "" msgid "Shown in lists and maps" msgstr "" +msgid "Name" +msgstr "" + msgid "Official name" msgstr "" +msgid "Comments" +msgstr "" + msgid "Remarks" msgstr "" +msgid "Departure" +msgstr "" + msgid "Departure place" msgstr "" +msgid "Arrival" +msgstr "" + msgid "Arrival place" msgstr "" diff --git a/geotrek/core/locale/en/LC_MESSAGES/django.po b/geotrek/core/locale/en/LC_MESSAGES/django.po index 2b76429524..4680fced2d 100644 --- a/geotrek/core/locale/en/LC_MESSAGES/django.po +++ b/geotrek/core/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -43,21 +43,9 @@ msgstr "" msgid "Valid geometry" msgstr "" -msgid "Name" -msgstr "" - -msgid "Comments" -msgstr "" - msgid "Provider" msgstr "" -msgid "Departure" -msgstr "" - -msgid "Arrival" -msgstr "" - msgid "Certification labels" msgstr "" @@ -115,15 +103,27 @@ msgstr "" msgid "Shown in lists and maps" msgstr "" +msgid "Name" +msgstr "" + msgid "Official name" msgstr "" +msgid "Comments" +msgstr "" + msgid "Remarks" msgstr "" +msgid "Departure" +msgstr "" + msgid "Departure place" msgstr "" +msgid "Arrival" +msgstr "" + msgid "Arrival place" msgstr "" diff --git a/geotrek/core/locale/es/LC_MESSAGES/django.po b/geotrek/core/locale/es/LC_MESSAGES/django.po index 1c560271cd..33701e9eab 100644 --- a/geotrek/core/locale/es/LC_MESSAGES/django.po +++ b/geotrek/core/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Spanish \n" @@ -43,21 +43,9 @@ msgstr "" msgid "Valid geometry" msgstr "" -msgid "Name" -msgstr "" - -msgid "Comments" -msgstr "" - msgid "Provider" msgstr "" -msgid "Departure" -msgstr "" - -msgid "Arrival" -msgstr "" - msgid "Certification labels" msgstr "" @@ -115,15 +103,27 @@ msgstr "" msgid "Shown in lists and maps" msgstr "" +msgid "Name" +msgstr "" + msgid "Official name" msgstr "" +msgid "Comments" +msgstr "" + msgid "Remarks" msgstr "" +msgid "Departure" +msgstr "" + msgid "Departure place" msgstr "" +msgid "Arrival" +msgstr "" + msgid "Arrival place" msgstr "" diff --git a/geotrek/core/locale/fr/LC_MESSAGES/django.po b/geotrek/core/locale/fr/LC_MESSAGES/django.po index d8301d8f17..29c5170491 100644 --- a/geotrek/core/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/core/locale/fr/LC_MESSAGES/django.po @@ -43,21 +43,9 @@ msgstr "Topologie valide" msgid "Valid geometry" msgstr "Géometrie valide" -msgid "Name" -msgstr "Nom" - -msgid "Comments" -msgstr "Commentaires" - msgid "Provider" msgstr "Fournisseur" -msgid "Departure" -msgstr "Départ" - -msgid "Arrival" -msgstr "Arrivée" - msgid "Certification labels" msgstr "Labellisations" @@ -115,15 +103,27 @@ msgstr "Visible" msgid "Shown in lists and maps" msgstr "Affiché dans les listes et sur les cartes" +msgid "Name" +msgstr "Nom" + msgid "Official name" msgstr "Nom officiel" +msgid "Comments" +msgstr "Commentaires" + msgid "Remarks" msgstr "Remarques" +msgid "Departure" +msgstr "Départ" + msgid "Departure place" msgstr "Lieu de départ" +msgid "Arrival" +msgstr "Arrivée" + msgid "Arrival place" msgstr "Lieu d'arrivée" diff --git a/geotrek/core/locale/it/LC_MESSAGES/django.po b/geotrek/core/locale/it/LC_MESSAGES/django.po index db4a006f78..88ce6dc965 100644 --- a/geotrek/core/locale/it/LC_MESSAGES/django.po +++ b/geotrek/core/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Italian \n" @@ -43,21 +43,9 @@ msgstr "" msgid "Valid geometry" msgstr "" -msgid "Name" -msgstr "" - -msgid "Comments" -msgstr "" - msgid "Provider" msgstr "" -msgid "Departure" -msgstr "" - -msgid "Arrival" -msgstr "" - msgid "Certification labels" msgstr "" @@ -115,15 +103,27 @@ msgstr "" msgid "Shown in lists and maps" msgstr "" +msgid "Name" +msgstr "" + msgid "Official name" msgstr "" +msgid "Comments" +msgstr "" + msgid "Remarks" msgstr "" +msgid "Departure" +msgstr "" + msgid "Departure place" msgstr "" +msgid "Arrival" +msgstr "" + msgid "Arrival place" msgstr "" diff --git a/geotrek/core/locale/nl/LC_MESSAGES/django.po b/geotrek/core/locale/nl/LC_MESSAGES/django.po index b871289b38..68d00c585a 100644 --- a/geotrek/core/locale/nl/LC_MESSAGES/django.po +++ b/geotrek/core/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dutch \n" @@ -43,21 +43,9 @@ msgstr "" msgid "Valid geometry" msgstr "" -msgid "Name" -msgstr "" - -msgid "Comments" -msgstr "" - msgid "Provider" msgstr "" -msgid "Departure" -msgstr "" - -msgid "Arrival" -msgstr "" - msgid "Certification labels" msgstr "" @@ -115,15 +103,27 @@ msgstr "" msgid "Shown in lists and maps" msgstr "" +msgid "Name" +msgstr "" + msgid "Official name" msgstr "" +msgid "Comments" +msgstr "" + msgid "Remarks" msgstr "" +msgid "Departure" +msgstr "" + msgid "Departure place" msgstr "" +msgid "Arrival" +msgstr "" + msgid "Arrival place" msgstr "" diff --git a/geotrek/feedback/filters.py b/geotrek/feedback/filters.py index 254733277d..3d2ea99886 100644 --- a/geotrek/feedback/filters.py +++ b/geotrek/feedback/filters.py @@ -1,3 +1,4 @@ +from dal import autocomplete from django.utils.translation import gettext_lazy as _ from django_filters import ModelMultipleChoiceFilter, MultipleChoiceFilter from mapentity.filters import MapEntityFilterSet @@ -13,15 +14,18 @@ class ReportFilterSet(ZoningFilterSet, MapEntityFilterSet): label=_("Creation year"), field_name="date_insert__year", choices=lambda: Report.objects.year_insert_choices(), + widget=autocomplete.Select2Multiple, ) year_update = MultipleChoiceFilter( label=_("Update year"), field_name="date_update__year", choices=lambda: Report.objects.year_update_choices(), + widget=autocomplete.Select2Multiple, ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(report__isnull=False).distinct(), + widget=autocomplete.Select2Multiple, ) class Meta(MapEntityFilterSet.Meta): diff --git a/geotrek/infrastructure/filters.py b/geotrek/infrastructure/filters.py index 2dfca631e5..4f061693a7 100644 --- a/geotrek/infrastructure/filters.py +++ b/geotrek/infrastructure/filters.py @@ -1,8 +1,8 @@ +from dal import autocomplete from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.utils.translation import gettext_lazy as _ from django_filters import ( - CharFilter, ModelMultipleChoiceFilter, MultipleChoiceFilter, ) @@ -28,39 +28,49 @@ class InfrastructureFilterSet( ZoningFilterSet, StructureRelatedFilterSet, ): - name = CharFilter(label=_("Name"), lookup_expr="icontains") - description = CharFilter(label=_("Description"), lookup_expr="icontains") implantation_year = MultipleChoiceFilter( - choices=lambda: Infrastructure.objects.implantation_year_choices() + choices=lambda: Infrastructure.objects.implantation_year_choices(), + widget=autocomplete.Select2Multiple(), ) intervention_year = MultipleChoiceFilter( label=_("Intervention year"), method="filter_intervention_year", choices=lambda: Intervention.objects.year_choices(), + widget=autocomplete.Select2Multiple(), ) category = MultipleChoiceFilter( label=_("Category"), field_name="type__type", choices=InfrastructureTypeChoices.choices, + widget=autocomplete.Select2Multiple(), + ) + trail = TopologyFilterTrail( + label=_("Trail"), + required=False, + widget=autocomplete.Select2Multiple(), ) - trail = TopologyFilterTrail(label=_("Trail"), required=False) maintenance_difficulty = ModelMultipleChoiceFilter( queryset=InfrastructureMaintenanceDifficultyLevel.objects.all(), label=_("Maintenance difficulty"), + widget=autocomplete.Select2Multiple(), ) usage_difficulty = ModelMultipleChoiceFilter( queryset=InfrastructureUsageDifficultyLevel.objects.all(), label=_("Usage difficulty"), + widget=autocomplete.Select2Multiple(), ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(infrastructure__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): model = Infrastructure fields = [ *StructureRelatedFilterSet.Meta.fields, + "name", + "description", "category", "type", "conditions", diff --git a/geotrek/infrastructure/locale/de/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/de/LC_MESSAGES/django.po index 5c7d45f6be..eb5f805f7d 100644 --- a/geotrek/infrastructure/locale/de/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "" -msgid "Name" -msgstr "" - -msgid "Description" -msgstr "" - msgid "Intervention year" msgstr "" @@ -66,6 +60,9 @@ msgstr "" msgid "Access means" msgstr "" +msgid "Name" +msgstr "" + msgid "Infrastructure Condition" msgstr "" @@ -84,6 +81,9 @@ msgstr "" msgid "Reference, code, ..." msgstr "" +msgid "Description" +msgstr "" + msgid "Specificites" msgstr "" diff --git a/geotrek/infrastructure/locale/en/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/en/LC_MESSAGES/django.po index 24cea2c0a5..82c984f045 100644 --- a/geotrek/infrastructure/locale/en/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "" -msgid "Name" -msgstr "" - -msgid "Description" -msgstr "" - msgid "Intervention year" msgstr "" @@ -66,6 +60,9 @@ msgstr "" msgid "Access means" msgstr "" +msgid "Name" +msgstr "" + msgid "Infrastructure Condition" msgstr "" @@ -84,6 +81,9 @@ msgstr "" msgid "Reference, code, ..." msgstr "" +msgid "Description" +msgstr "" + msgid "Specificites" msgstr "" diff --git a/geotrek/infrastructure/locale/es/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/es/LC_MESSAGES/django.po index ce2b126066..292516c8af 100644 --- a/geotrek/infrastructure/locale/es/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Spanish \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "" -msgid "Name" -msgstr "" - -msgid "Description" -msgstr "" - msgid "Intervention year" msgstr "" @@ -66,6 +60,9 @@ msgstr "" msgid "Access means" msgstr "" +msgid "Name" +msgstr "" + msgid "Infrastructure Condition" msgstr "" @@ -84,6 +81,9 @@ msgstr "" msgid "Reference, code, ..." msgstr "" +msgid "Description" +msgstr "" + msgid "Specificites" msgstr "" diff --git a/geotrek/infrastructure/locale/fr/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/fr/LC_MESSAGES/django.po index df95e84591..6da2081431 100644 --- a/geotrek/infrastructure/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: J-E Castagnede \n" "Language-Team: French \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "Aménagement" -msgid "Name" -msgstr "Nom" - -msgid "Description" -msgstr "Description" - msgid "Intervention year" msgstr "Année d'intervention" @@ -66,6 +60,9 @@ msgstr "Moyen d'accès" msgid "Access means" msgstr "Moyens d'accès" +msgid "Name" +msgstr "Nom" + msgid "Infrastructure Condition" msgstr "Etat d'aménagement" @@ -84,6 +81,9 @@ msgstr "Niveaux des usagers" msgid "Reference, code, ..." msgstr "Référence, code, ..." +msgid "Description" +msgstr "Description" + msgid "Specificites" msgstr "Spécificités" diff --git a/geotrek/infrastructure/locale/it/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/it/LC_MESSAGES/django.po index d855255a82..a912b4c54e 100644 --- a/geotrek/infrastructure/locale/it/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Italian \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "" -msgid "Name" -msgstr "" - -msgid "Description" -msgstr "" - msgid "Intervention year" msgstr "" @@ -66,6 +60,9 @@ msgstr "" msgid "Access means" msgstr "" +msgid "Name" +msgstr "" + msgid "Infrastructure Condition" msgstr "" @@ -84,6 +81,9 @@ msgstr "" msgid "Reference, code, ..." msgstr "" +msgid "Description" +msgstr "" + msgid "Specificites" msgstr "" diff --git a/geotrek/infrastructure/locale/nl/LC_MESSAGES/django.po b/geotrek/infrastructure/locale/nl/LC_MESSAGES/django.po index 57460d80e3..c9c5414cbe 100644 --- a/geotrek/infrastructure/locale/nl/LC_MESSAGES/django.po +++ b/geotrek/infrastructure/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-22 09:48+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dutch \n" @@ -21,12 +21,6 @@ msgstr "" msgid "Infrastructure" msgstr "" -msgid "Name" -msgstr "" - -msgid "Description" -msgstr "" - msgid "Intervention year" msgstr "" @@ -66,6 +60,9 @@ msgstr "" msgid "Access means" msgstr "" +msgid "Name" +msgstr "" + msgid "Infrastructure Condition" msgstr "" @@ -84,6 +81,9 @@ msgstr "" msgid "Reference, code, ..." msgstr "" +msgid "Description" +msgstr "" + msgid "Specificites" msgstr "" diff --git a/geotrek/land/filters.py b/geotrek/land/filters.py index 3f851bfb89..963e02820c 100644 --- a/geotrek/land/filters.py +++ b/geotrek/land/filters.py @@ -1,3 +1,4 @@ +from dal import autocomplete from django.utils.translation import gettext_lazy as _ from mapentity.filters import MapEntityFilterSet @@ -12,7 +13,6 @@ from geotrek.maintenance.filters import InterventionFilterSet, ProjectFilterSet from geotrek.signage.filters import SignageFilterSet from geotrek.trekking.filters import POIFilterSet, TrekFilterSet -from geotrek.zoning.filters import * # NOQA from .models import ( AuthorizationType, @@ -137,24 +137,40 @@ def values_to_edges(self, values): def add_edge_filters(filter_set): filter_set.add_filters( { - "land_type": TopologyFilterLandType(label=_("Land edge"), required=False), + "land_type": TopologyFilterLandType( + label=_("Land edge"), + required=False, + widget=autocomplete.Select2Multiple(), + ), "physical_type": TopologyFilterPhysicalType( - label=_("Physical edge"), required=False + label=_("Physical edge"), + required=False, + widget=autocomplete.Select2Multiple(), ), "circulation_type": TopologyFilterCirculationType( - label=_("Circulation edge"), required=False + label=_("Circulation type"), + required=False, + widget=autocomplete.Select2Multiple(), ), "authorization_type": TopologyFilterAuthorizationType( - label=_("Circulation edge"), required=False + label=_("Circulation edge"), + required=False, + widget=autocomplete.Select2Multiple(), ), "competence": TopologyFilterCompetenceEdge( - label=_("Competence edge"), required=False + label=_("Competence edge"), + required=False, + widget=autocomplete.Select2Multiple(), ), "signage": TopologyFilterSignageManagementEdge( - label=_("Signage management edge"), required=False + label=_("Signage management edge"), + required=False, + widget=autocomplete.Select2Multiple(), ), "work": TopologyFilterWorkManagementEdge( - label=_("Work management edge"), required=False + label=_("Work management edge"), + required=False, + widget=autocomplete.Select2Multiple(), ), } ) diff --git a/geotrek/land/locale/de/LC_MESSAGES/django.po b/geotrek/land/locale/de/LC_MESSAGES/django.po index f45eb1a795..ab27e4d13c 100644 --- a/geotrek/land/locale/de/LC_MESSAGES/django.po +++ b/geotrek/land/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-03 15:39+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" @@ -27,6 +27,9 @@ msgstr "" msgid "Physical edge" msgstr "" +msgid "Circulation type" +msgstr "" + msgid "Circulation edge" msgstr "" @@ -90,9 +93,6 @@ msgstr "" msgid "Signage management edges" msgstr "" -msgid "Circulation type" -msgstr "" - msgid "Circulation types" msgstr "" diff --git a/geotrek/land/locale/en/LC_MESSAGES/django.po b/geotrek/land/locale/en/LC_MESSAGES/django.po index 610d136586..ef9f92665b 100644 --- a/geotrek/land/locale/en/LC_MESSAGES/django.po +++ b/geotrek/land/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-03 15:39+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -27,6 +27,9 @@ msgstr "" msgid "Physical edge" msgstr "" +msgid "Circulation type" +msgstr "" + msgid "Circulation edge" msgstr "" @@ -90,9 +93,6 @@ msgstr "" msgid "Signage management edges" msgstr "" -msgid "Circulation type" -msgstr "" - msgid "Circulation types" msgstr "" diff --git a/geotrek/land/locale/es/LC_MESSAGES/django.po b/geotrek/land/locale/es/LC_MESSAGES/django.po index db97f8093f..3d0499811b 100644 --- a/geotrek/land/locale/es/LC_MESSAGES/django.po +++ b/geotrek/land/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-03 15:39+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Spanish \n" @@ -27,6 +27,9 @@ msgstr "" msgid "Physical edge" msgstr "" +msgid "Circulation type" +msgstr "" + msgid "Circulation edge" msgstr "" @@ -90,9 +93,6 @@ msgstr "" msgid "Signage management edges" msgstr "" -msgid "Circulation type" -msgstr "" - msgid "Circulation types" msgstr "" diff --git a/geotrek/land/locale/fr/LC_MESSAGES/django.po b/geotrek/land/locale/fr/LC_MESSAGES/django.po index 5ad1dda378..ca7bce3336 100644 --- a/geotrek/land/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/land/locale/fr/LC_MESSAGES/django.po @@ -27,6 +27,9 @@ msgstr "Type foncier" msgid "Physical edge" msgstr "Type de voie" +msgid "Circulation type" +msgstr "Type de circulation" + msgid "Circulation edge" msgstr "Circulation" @@ -90,9 +93,6 @@ msgstr "Gestionnaires travaux" msgid "Signage management edges" msgstr "Gestionnaires signalétique" -msgid "Circulation type" -msgstr "Type de circulation" - msgid "Circulation types" msgstr "Types de circulation" diff --git a/geotrek/land/locale/it/LC_MESSAGES/django.po b/geotrek/land/locale/it/LC_MESSAGES/django.po index 8680208d83..67129509cb 100644 --- a/geotrek/land/locale/it/LC_MESSAGES/django.po +++ b/geotrek/land/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-03 15:39+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Italian \n" @@ -27,6 +27,9 @@ msgstr "" msgid "Physical edge" msgstr "" +msgid "Circulation type" +msgstr "" + msgid "Circulation edge" msgstr "" @@ -90,9 +93,6 @@ msgstr "" msgid "Signage management edges" msgstr "" -msgid "Circulation type" -msgstr "" - msgid "Circulation types" msgstr "" diff --git a/geotrek/land/locale/nl/LC_MESSAGES/django.po b/geotrek/land/locale/nl/LC_MESSAGES/django.po index 0f8bfb6f25..8eb46883c4 100644 --- a/geotrek/land/locale/nl/LC_MESSAGES/django.po +++ b/geotrek/land/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-03 15:39+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dutch \n" @@ -27,6 +27,9 @@ msgstr "" msgid "Physical edge" msgstr "" +msgid "Circulation type" +msgstr "" + msgid "Circulation edge" msgstr "" @@ -90,9 +93,6 @@ msgstr "" msgid "Signage management edges" msgstr "" -msgid "Circulation type" -msgstr "" - msgid "Circulation types" msgstr "" diff --git a/geotrek/maintenance/filters.py b/geotrek/maintenance/filters.py index bbbf9be914..6172e0cbca 100644 --- a/geotrek/maintenance/filters.py +++ b/geotrek/maintenance/filters.py @@ -1,3 +1,4 @@ +from dal import autocomplete from django.conf import settings from django.contrib.gis.geos import GeometryCollection from django.db.models import Q @@ -190,7 +191,7 @@ class InterventionFilterSet( widget=OneLineRangeWidget( attrs={ "type": "text", - "class": "minmax-field", + "class": "minmax-field form-control form-control-sm", "title": _("Filter by begin date range"), }, ), @@ -200,7 +201,7 @@ class InterventionFilterSet( widget=OneLineRangeWidget( attrs={ "type": "text", - "class": "minmax-field", + "class": "minmax-field form-control form-control-sm", "title": _("Filter by end date range"), }, ), @@ -210,24 +211,50 @@ class InterventionFilterSet( choices=lambda: Intervention.objects.year_choices(), method="filter_year", label=_("Year"), + widget=autocomplete.Select2Multiple(), ) on = ChoiceFilter( field_name="target_type__model", choices=ON_CHOICES, label=_("On"), empty_label=_("On"), + widget=autocomplete.Select2(), ) area_type = InterventionIntersectionFilterRestrictedAreaType( - label=_("Restricted area type"), required=False, lookup_expr="intersects" + label=_("Restricted area type"), + required=False, + lookup_expr="intersects", + widget=autocomplete.Select2Multiple(), ) area = InterventionIntersectionFilterRestrictedArea( - label=_("Restricted area"), required=False, lookup_expr="intersects" + label=_("Restricted area"), + required=False, + lookup_expr="intersects", + widget=autocomplete.Select2Multiple(), ) city = InterventionIntersectionFilterCity( - label=_("City"), required=False, lookup_expr="intersects" + label=_("City"), + required=False, + lookup_expr="intersects", + widget=autocomplete.ModelSelect2Multiple( + url="zoning:city-autocomplete", + attrs={ + "data-placeholder": _("City"), + #'data-theme': 'bootstrap4' + }, + ), ) district = InterventionIntersectionFilterDistrict( - label=_("District"), required=False, lookup_expr="intersects" + label=_("District"), + required=False, + lookup_expr="intersects", + widget=autocomplete.ModelSelect2Multiple( + url="zoning:district-autocomplete", + attrs={ + "data-placeholder": _("City"), + # 'data-theme': 'bootstrap4' + }, + ), ) class Meta(StructureRelatedFilterSet.Meta): @@ -266,23 +293,49 @@ class ProjectFilterSet(StructureRelatedFilterSet): label=_("Year of activity"), method="filter_year", choices=lambda: Project.objects.year_choices(), + widget=autocomplete.Select2Multiple(), ) city = ProjectIntersectionFilterCity( - label=_("City"), lookup_expr="intersects", required=False + label=_("City"), + lookup_expr="intersects", + required=False, + widget=autocomplete.ModelSelect2Multiple( + url="zoning:city-autocomplete", + attrs={ + "data-placeholder": _("City"), + #'data-theme': 'bootstrap4' + }, + ), ) district = ProjectIntersectionFilterDistrict( - label=_("District"), lookup_expr="intersects", required=False + label=_("District"), + lookup_expr="intersects", + required=False, + widget=autocomplete.ModelSelect2Multiple( + url="zoning:district-autocomplete", + attrs={ + "data-placeholder": _("City"), + # 'data-theme': 'bootstrap4' + }, + ), ) area_type = ProjectIntersectionFilterRestrictedAreaType( - label=_("Restricted area type"), lookup_expr="intersects", required=False + label=_("Restricted area type"), + lookup_expr="intersects", + required=False, + widget=autocomplete.Select2Multiple(), ) area = ProjectIntersectionFilterRestrictedArea( - label=_("Restricted area"), lookup_expr="intersects", required=False + label=_("Restricted area"), + lookup_expr="intersects", + required=False, + widget=autocomplete.Select2Multiple(), ) contractors = ModelMultipleChoiceFilter( label=_("Contractors"), queryset=Contractor.objects.all(), method="filter_contractors", + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): diff --git a/geotrek/outdoor/filters.py b/geotrek/outdoor/filters.py index debef3547d..7feb1e4daf 100644 --- a/geotrek/outdoor/filters.py +++ b/geotrek/outdoor/filters.py @@ -1,3 +1,4 @@ +from dal import autocomplete from django.db.models import Q from django.utils.translation import gettext as _ from django_filters.filters import ( @@ -13,21 +14,36 @@ class SiteFilterSet(ZoningFilterSet, StructureRelatedFilterSet): orientation = MultipleChoiceFilter( - choices=Site.ORIENTATION_CHOICES, method="filter_orientation" + choices=Site.ORIENTATION_CHOICES, + method="filter_orientation", + widget=autocomplete.Select2Multiple(), + ) + wind = MultipleChoiceFilter( + choices=Site.WIND_CHOICES, + method="filter_orientation", + widget=autocomplete.Select2Multiple(), ) - wind = MultipleChoiceFilter(choices=Site.WIND_CHOICES, method="filter_orientation") practice = ModelMultipleChoiceFilter( - queryset=Practice.objects.all(), method="filter_super" + queryset=Practice.objects.all(), + method="filter_super", + widget=autocomplete.Select2Multiple(), ) sector = ModelMultipleChoiceFilter( - queryset=Sector.objects.all(), method="filter_sector", label=_("Sector") + queryset=Sector.objects.all(), + method="filter_sector", + label=_("Sector"), + widget=autocomplete.Select2Multiple(), ) managers = ModelMultipleChoiceFilter( - queryset=Organism.objects.all(), method="filter_manager", label=_("Manager") + queryset=Organism.objects.all(), + method="filter_manager", + label=_("Manager"), + widget=autocomplete.Select2Multiple(), ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(site__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): @@ -76,13 +92,18 @@ class CourseFilterSet(ZoningFilterSet, StructureRelatedFilterSet): choices=Site.ORIENTATION_CHOICES, method="filter_orientation", label=_("Orientation"), + widget=autocomplete.Select2Multiple(), ) wind = MultipleChoiceFilter( - choices=Site.WIND_CHOICES, method="filter_orientation", label=_("Wind") + choices=Site.WIND_CHOICES, + method="filter_orientation", + label=_("Wind"), + widget=autocomplete.Select2Multiple(), ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(course__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): diff --git a/geotrek/outdoor/locale/de/LC_MESSAGES/django.po b/geotrek/outdoor/locale/de/LC_MESSAGES/django.po index 8ddee52962..101c1dcbac 100644 --- a/geotrek/outdoor/locale/de/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" @@ -310,12 +310,6 @@ msgstr "" msgid "External id" msgstr "" -msgid "No result" -msgstr "" - -msgid "Choose value(s)" -msgstr "" - msgid "Powered by geotrek.fr" msgstr "" diff --git a/geotrek/outdoor/locale/en/LC_MESSAGES/django.po b/geotrek/outdoor/locale/en/LC_MESSAGES/django.po index f106c2c370..4f697a84b3 100644 --- a/geotrek/outdoor/locale/en/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:11+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -310,12 +310,6 @@ msgstr "" msgid "External id" msgstr "" -msgid "No result" -msgstr "" - -msgid "Choose value(s)" -msgstr "" - msgid "Powered by geotrek.fr" msgstr "" diff --git a/geotrek/outdoor/locale/es/LC_MESSAGES/django.po b/geotrek/outdoor/locale/es/LC_MESSAGES/django.po index 56c981ad9b..b60a93f186 100644 --- a/geotrek/outdoor/locale/es/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:59+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Spanish \n" @@ -310,12 +310,6 @@ msgstr "" msgid "External id" msgstr "" -msgid "No result" -msgstr "" - -msgid "Choose value(s)" -msgstr "" - msgid "Powered by geotrek.fr" msgstr "" diff --git a/geotrek/outdoor/locale/fr/LC_MESSAGES/django.po b/geotrek/outdoor/locale/fr/LC_MESSAGES/django.po index 4dad2dcf25..28fe887962 100644 --- a/geotrek/outdoor/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 16:15+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: J-E Castagnede \n" "Language-Team: French \n" @@ -310,12 +310,6 @@ msgstr "Parent de :" msgid "External id" msgstr "ID externe" -msgid "No result" -msgstr "Pas de résultat" - -msgid "Choose value(s)" -msgstr "Choisir une ou des valeur(s)" - msgid "Powered by geotrek.fr" msgstr "Propulsé par geotrek.fr" diff --git a/geotrek/outdoor/locale/it/LC_MESSAGES/django.po b/geotrek/outdoor/locale/it/LC_MESSAGES/django.po index d5b0ceb4c2..3d754a383e 100644 --- a/geotrek/outdoor/locale/it/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:59+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Italian \n" @@ -310,12 +310,6 @@ msgstr "" msgid "External id" msgstr "" -msgid "No result" -msgstr "" - -msgid "Choose value(s)" -msgstr "" - msgid "Powered by geotrek.fr" msgstr "" diff --git a/geotrek/outdoor/locale/nl/LC_MESSAGES/django.po b/geotrek/outdoor/locale/nl/LC_MESSAGES/django.po index 3ecff26ddb..bb0647fc2b 100644 --- a/geotrek/outdoor/locale/nl/LC_MESSAGES/django.po +++ b/geotrek/outdoor/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-23 11:59+0000\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dutch \n" @@ -310,12 +310,6 @@ msgstr "" msgid "External id" msgstr "" -msgid "No result" -msgstr "" - -msgid "Choose value(s)" -msgstr "" - msgid "Powered by geotrek.fr" msgstr "" diff --git a/geotrek/outdoor/templates/outdoor/course_form.html b/geotrek/outdoor/templates/outdoor/course_form.html index 1f8ba5db23..8eecb82247 100644 --- a/geotrek/outdoor/templates/outdoor/course_form.html +++ b/geotrek/outdoor/templates/outdoor/course_form.html @@ -17,11 +17,6 @@ }); diff --git a/geotrek/sensitivity/admin.py b/geotrek/sensitivity/admin.py index 45c601bdfa..fd7a029e96 100644 --- a/geotrek/sensitivity/admin.py +++ b/geotrek/sensitivity/admin.py @@ -27,4 +27,8 @@ class SpeciesAdmin(MergeActionMixin, admin.ModelAdmin): merge_field = "name" def get_queryset(self, request): - return super().get_queryset(request).filter(category=Species.SPECIES) + return ( + super() + .get_queryset(request) + .filter(category=Species.CategoryChoices.SPECIES) + ) diff --git a/geotrek/sensitivity/filters.py b/geotrek/sensitivity/filters.py index c3fdf04713..e41b67bac0 100644 --- a/geotrek/sensitivity/filters.py +++ b/geotrek/sensitivity/filters.py @@ -1,5 +1,7 @@ +from dal import autocomplete from django.utils.translation import gettext as _ from django.utils.translation import pgettext_lazy +from django_filters import MultipleChoiceFilter from django_filters.filters import ModelMultipleChoiceFilter from geotrek.authent.filters import StructureRelatedFilterSet @@ -11,11 +13,20 @@ class SensitiveAreaFilterSet(StructureRelatedFilterSet): species = ModelMultipleChoiceFilter( label=pgettext_lazy("Singular", "Species"), - queryset=Species.objects.filter(category=Species.SPECIES), + queryset=Species.objects.filter(category=Species.CategoryChoices.SPECIES), + widget=autocomplete.Select2Multiple(), + ) + category = MultipleChoiceFilter( + label=_("Category"), + field_name="species__category", + widget=autocomplete.Select2Multiple(), + choices=Species.CategoryChoices.choices, + required=False, ) provider = ModelMultipleChoiceFilter( label=_("Provider"), queryset=Provider.objects.filter(sensitivearea__isnull=False).distinct(), + widget=autocomplete.Select2Multiple(), ) class Meta(StructureRelatedFilterSet.Meta): @@ -23,6 +34,6 @@ class Meta(StructureRelatedFilterSet.Meta): fields = [ *StructureRelatedFilterSet.Meta.fields, "species", - "species__category", + "category", "provider", ] diff --git a/geotrek/sensitivity/forms.py b/geotrek/sensitivity/forms.py index bd81ce8999..82bd0322e1 100644 --- a/geotrek/sensitivity/forms.py +++ b/geotrek/sensitivity/forms.py @@ -24,7 +24,7 @@ class PolygonMapWidget(MapWidget): class SensitiveAreaForm(CommonForm): geomfields = ["geom"] species = forms.ModelChoiceField( - queryset=Species.objects.filter(category=Species.SPECIES), + queryset=Species.objects.filter(category=Species.CategoryChoices.SPECIES), label=pgettext("Singular", "Species"), ) @@ -93,14 +93,14 @@ def __init__(self, *args, **kwargs): kwargs["initial"][name] = getattr(species, name) super().__init__(*args, **kwargs) - self.helper.form_action += f"?category={Species.REGULATORY}" + self.helper.form_action += f"?category={Species.CategoryChoices.REGULATORY}" def save(self, **kwargs): if not self.instance.pk: species = Species() else: species = self.instance.species - species.category = Species.REGULATORY + species.category = Species.CategoryChoices.REGULATORY species.name = self.cleaned_data["name"] species.radius = self.cleaned_data["elevation"] species.pictogram = self.cleaned_data["pictogram"] diff --git a/geotrek/sensitivity/locale/de/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/de/LC_MESSAGES/django.po index 59dafbe94d..a11cada0c7 100644 --- a/geotrek/sensitivity/locale/de/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "" +msgid "Category" +msgstr "" + msgid "Provider" msgstr "" @@ -94,16 +97,13 @@ msgstr "" msgid "Sport practice" msgstr "" -msgid "Bubble radius" -msgstr "" - -msgid "meters" +msgid "Regulatory" msgstr "" -msgid "Category" +msgid "Bubble radius" msgstr "" -msgid "Regulatory" +msgid "meters" msgstr "" msgid "External id" diff --git a/geotrek/sensitivity/locale/en/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/en/LC_MESSAGES/django.po index 19c1ca5ac9..3786d05e5c 100644 --- a/geotrek/sensitivity/locale/en/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "" +msgid "Category" +msgstr "" + msgid "Provider" msgstr "" @@ -94,16 +97,13 @@ msgstr "" msgid "Sport practice" msgstr "" -msgid "Bubble radius" -msgstr "" - -msgid "meters" +msgid "Regulatory" msgstr "" -msgid "Category" +msgid "Bubble radius" msgstr "" -msgid "Regulatory" +msgid "meters" msgstr "" msgid "External id" diff --git a/geotrek/sensitivity/locale/es/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/es/LC_MESSAGES/django.po index f117c66a89..85097d618d 100644 --- a/geotrek/sensitivity/locale/es/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Spanish \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "" +msgid "Category" +msgstr "" + msgid "Provider" msgstr "" @@ -94,16 +97,13 @@ msgstr "" msgid "Sport practice" msgstr "" -msgid "Bubble radius" -msgstr "" - -msgid "meters" +msgid "Regulatory" msgstr "" -msgid "Category" +msgid "Bubble radius" msgstr "" -msgid "Regulatory" +msgid "meters" msgstr "" msgid "External id" diff --git a/geotrek/sensitivity/locale/fr/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/fr/LC_MESSAGES/django.po index 882ae2d36e..ad5ae6fe45 100644 --- a/geotrek/sensitivity/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:00+0000\n" "Last-Translator: J-E Castagnede \n" "Language-Team: French \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "Espèce" +msgid "Category" +msgstr "Catégorie" + msgid "Provider" msgstr "Fournisseur" @@ -94,18 +97,15 @@ msgstr "Règles" msgid "Sport practice" msgstr "Pratique sportive" +msgid "Regulatory" +msgstr "Réglementaire" + msgid "Bubble radius" msgstr "Rayon de la bulle" msgid "meters" msgstr "mètres" -msgid "Category" -msgstr "Catégorie" - -msgid "Regulatory" -msgstr "Réglementaire" - msgid "External id" msgstr "ID externe" diff --git a/geotrek/sensitivity/locale/it/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/it/LC_MESSAGES/django.po index 168844b8f3..b1addf5886 100644 --- a/geotrek/sensitivity/locale/it/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Italian \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "" +msgid "Category" +msgstr "" + msgid "Provider" msgstr "" @@ -94,16 +97,13 @@ msgstr "Regole" msgid "Sport practice" msgstr "" -msgid "Bubble radius" -msgstr "" - -msgid "meters" +msgid "Regulatory" msgstr "" -msgid "Category" +msgid "Bubble radius" msgstr "" -msgid "Regulatory" +msgid "meters" msgstr "" msgid "External id" diff --git a/geotrek/sensitivity/locale/nl/LC_MESSAGES/django.po b/geotrek/sensitivity/locale/nl/LC_MESSAGES/django.po index 952af318aa..4541fb840a 100644 --- a/geotrek/sensitivity/locale/nl/LC_MESSAGES/django.po +++ b/geotrek/sensitivity/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-04 11:40+0200\n" +"POT-Creation-Date: 2025-11-17 09:32+0000\n" "PO-Revision-Date: 2025-10-22 09:01+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dutch \n" @@ -25,6 +25,9 @@ msgctxt "Singular" msgid "Species" msgstr "" +msgid "Category" +msgstr "" + msgid "Provider" msgstr "" @@ -94,16 +97,13 @@ msgstr "" msgid "Sport practice" msgstr "" -msgid "Bubble radius" -msgstr "" - -msgid "meters" +msgid "Regulatory" msgstr "" -msgid "Category" +msgid "Bubble radius" msgstr "" -msgid "Regulatory" +msgid "meters" msgstr "" msgid "External id" diff --git a/geotrek/sensitivity/models.py b/geotrek/sensitivity/models.py index 13fdea5315..c1ff18150a 100644 --- a/geotrek/sensitivity/models.py +++ b/geotrek/sensitivity/models.py @@ -5,6 +5,7 @@ from django.conf import settings from django.contrib.gis.db import models from django.contrib.gis.geos import GEOSGeometry, Polygon +from django.db.models import IntegerChoices from django.utils.translation import gettext_lazy as _ from django.utils.translation import pgettext_lazy from mapentity.serializers import plain_text @@ -58,8 +59,9 @@ def __str__(self): class Species(TimeStampedModelMixin, OptionalPictogramMixin): - SPECIES = 1 - REGULATORY = 2 + class CategoryChoices(IntegerChoices): + SPECIES = 1, pgettext_lazy("Singular", "Species") + REGULATORY = 2, _("Regulatory") name = models.CharField(max_length=250, verbose_name=_("Name")) # TODO: we should replace these 12 fields by a unique JSONField @@ -83,11 +85,8 @@ class Species(TimeStampedModelMixin, OptionalPictogramMixin): category = models.IntegerField( verbose_name=_("Category"), editable=False, - default=SPECIES, - choices=( - (SPECIES, pgettext_lazy("Singular", "Species")), - (REGULATORY, _("Regulatory")), - ), + default=CategoryChoices.SPECIES, + choices=CategoryChoices, ) eid = models.CharField( verbose_name=_("External id"), max_length=1024, blank=True, null=True diff --git a/geotrek/sensitivity/parsers.py b/geotrek/sensitivity/parsers.py index c103f83d60..ef967ee985 100644 --- a/geotrek/sensitivity/parsers.py +++ b/geotrek/sensitivity/parsers.py @@ -107,12 +107,12 @@ def filter_species(self, src, val): try: species = self.obj.species except Species.DoesNotExist: - species = Species(category=Species.REGULATORY) + species = Species(category=Species.CategoryChoices.REGULATORY) else: # Species area try: species = Species.objects.get(eid=eid) except Species.DoesNotExist: - species = Species(category=Species.SPECIES, eid=eid) + species = Species(category=Species.CategoryChoices.SPECIES, eid=eid) for lang, translation in names.items(): if lang in settings.MODELTRANSLATION_LANGUAGES and translation != getattr( species, "name_" + lang @@ -158,7 +158,9 @@ class SpeciesSensitiveAreaShapeParser(ShapeParser): def filter_species(self, src, val): try: - species = Species.objects.get(category=Species.SPECIES, name=val) + species = Species.objects.get( + category=Species.CategoryChoices.SPECIES, name=val + ) except Species.DoesNotExist: msg = f"L'espèce {val} n'existe pas dans Geotrek. Merci de la créer." raise RowImportError(msg) @@ -191,7 +193,7 @@ class RegulatorySensitiveAreaShapeParser(ShapeParser): def filter_species(self, src, val): (name, elevation, period, practice_names, url) = val - species = Species(category=Species.REGULATORY) + species = Species(category=Species.CategoryChoices.REGULATORY) species.name = name if period: period = period.split(self.separator) diff --git a/geotrek/sensitivity/templates/sensitivity/sensitivearea_list.html b/geotrek/sensitivity/templates/sensitivity/sensitivearea_list.html index 6a9daf98af..45196ef69b 100644 --- a/geotrek/sensitivity/templates/sensitivity/sensitivearea_list.html +++ b/geotrek/sensitivity/templates/sensitivity/sensitivearea_list.html @@ -5,7 +5,7 @@ {% block mainactions %} {% if can_add %}