Skip to content

Commit

Permalink
Merge branch 'master' into feat/add_circulation_model
Browse files Browse the repository at this point in the history
  • Loading branch information
IdrissaD authored Oct 28, 2023
2 parents 3450711 + 6cf5f1f commit 2030c66
Show file tree
Hide file tree
Showing 35 changed files with 461 additions and 179 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.101.2+dev
2.101.3+dev
10 changes: 8 additions & 2 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
geotrek-admin (2.101.2+dev) UNRELEASED; urgency=medium
geotrek-admin (2.101.3+dev) UNRELEASED; urgency=medium

*

-- Célia Prat <[email protected]> Tue, 17 Oct 2023 17:15:50 +0200
-- Joaquim Nallar <[email protected]> Thu, 26 Oct 2023 12:04:29 +0200

geotrek-admin (2.101.3) RELEASED; urgency=medium

* New package release

-- Joaquim Nallar <[email protected]> Thu, 26 Oct 2023 10:57:23 +0200

geotrek-admin (2.101.2) RELEASED; urgency=medium

Expand Down
28 changes: 18 additions & 10 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CHANGELOG
=========


2.101.2+dev (XXXX-XX-XX)
2.101.3+dev (XXXX-XX-XX)
------------------------

**New features**
Expand All @@ -12,10 +12,18 @@ CHANGELOG

**Bug fixes**

- Fix `sync_rando` admin command failure if Trek has SVG attachment (#3803)
- Fix: filters choices can raise exception in lists and not updated until application restart (#3812)


2.101.3 (2023-10-26)
------------------------

**Bug fixes**

- Fix `sync_rando` admin command failure if Trek has SVG attachment (#3803)
- Fix provider choices in list filter forms

2.101.2 (2023-10-17)
2.101.2 (2023-10-17)
------------------------

**Bug fixes**
Expand All @@ -24,15 +32,15 @@ CHANGELOG
- Fix services list display error (refs ##3795)


2.101.1 (2023-10-06)
2.101.1 (2023-10-06)
------------------------

**Bug fixes**

- POI cirkwi XML endpoint is fixed (2.101.0 regression) (#3783)


2.101.0 (2023-10-05)
2.101.0 (2023-10-05)
------------------------

**New features**
Expand Down Expand Up @@ -63,7 +71,7 @@ CHANGELOG
- Update WYSIWYG link to help user when creating labels


2.100.2 (2023-09-12)
2.100.2 (2023-09-12)
------------------------

**Improvements**
Expand All @@ -88,7 +96,7 @@ CHANGELOG
- Increase length size of label on TouristicEventOrganizer model to fix migrations problems (#3719)


2.100.1 (2023-09-05)
2.100.1 (2023-09-05)
-------------------------

**Documentation**
Expand All @@ -104,7 +112,7 @@ CHANGELOG
- Remove unused folder 'bulkimport' from project (#3673)


2.100.0 (2023-09-05)
2.100.0 (2023-09-05)
-----------------------

**DO NOT USE**
Expand Down Expand Up @@ -143,7 +151,7 @@ CHANGELOG
- Upgrade `django-mapentity`


2.99.0 (2023-07-18)
2.99.0 (2023-07-18)
-----------------------

**New features**
Expand Down Expand Up @@ -171,7 +179,7 @@ CHANGELOG
- Upgrade `django-mapentity`


2.98.1 (2023-05-30)
2.98.1 (2023-05-30)
-----------------------

**Bug fixes**
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
# The short X.Y version.
version = '2.101'
# The full version, including alpha/beta/rc tags.
release = '2.101.2+dev'
release = '2.101.3+dev'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
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.
10 changes: 10 additions & 0 deletions geotrek/common/mixins/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ def get_queryset(self):
# Filter out deleted objects
def existing(self):
return self.get_queryset().filter(deleted=False)


class ProviderChoicesMixin:
def provider_choices(self):
qs = self.get_queryset()
if hasattr(qs, "existing"):
qs = qs.existing()
values = qs.exclude(provider__exact='') \
.distinct('provider').order_by("provider").values_list('provider', flat=True)
return tuple((value, value) for value in values)
4 changes: 2 additions & 2 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=Path.objects.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 @@ -130,7 +130,7 @@ class TrailFilterSet(AltimetryAllGeometriesFilterSet, ValidTopologyFilterSet, Zo
field_name='provider',
empty_label=_("Provider"),
label=_("Provider"),
choices=Trail.objects.provider_choices()
choices=lambda: Trail.objects.provider_choices()
)

class Meta(StructureRelatedFilterSet.Meta):
Expand Down
16 changes: 4 additions & 12 deletions geotrek/core/managers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.contrib.gis.db import models

from geotrek.common.functions import Length
from geotrek.common.mixins.managers import NoDeleteManager
from geotrek.common.mixins.managers import NoDeleteManager, ProviderChoicesMixin


class PathManager(models.Manager):
class PathManager(models.Manager, ProviderChoicesMixin):
# Use this manager when walking through FK/M2M relationships
use_for_related_fields = True

Expand All @@ -13,11 +13,6 @@ def get_queryset(self):
"""
return super().get_queryset().filter(visible=True).annotate(length_2d=Length('geom'))

def provider_choices(self):
providers = self.get_queryset().exclude(provider__exact='') \
.distinct('provider').values_list('provider', 'provider')
return providers


class PathInvisibleManager(models.Manager):
use_for_related_fields = True
Expand All @@ -39,8 +34,5 @@ def get_queryset(self):
return super().get_queryset().order_by('order')


class TrailManager(TopologyManager):
def provider_choices(self):
providers = self.get_queryset().existing().exclude(provider__exact='').order_by('provider') \
.distinct('provider').values_list('provider', 'provider')
return providers
class TrailManager(TopologyManager, ProviderChoicesMixin):
pass
67 changes: 58 additions & 9 deletions geotrek/core/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from geotrek.authent.tests.base import AuthentFixturesTest

from geotrek.core.models import Path, Trail, PathSource
from geotrek.core.filters import PathFilterSet, TrailFilterSet

from geotrek.trekking.tests.factories import POIFactory, TrekFactory, ServiceFactory
from geotrek.infrastructure.tests.factories import InfrastructureFactory
Expand Down Expand Up @@ -568,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 @@ -598,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 @@ -611,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 @@ -635,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 @@ -694,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 @@ -798,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 Expand Up @@ -873,3 +872,53 @@ def test_remove_poi(self):
self.assertEqual(poi.deleted, False)

self.assertAlmostEqual(1.5, poi.offset)


class PathFilterTest(CommonTest, AuthentFixturesTest):
factory = PathFactory
filterset = PathFilterSet

def test_provider_filter_without_provider(self):
filter_set = PathFilterSet(data={})
filter_form = filter_set.form

self.assertTrue(filter_form.is_valid())
self.assertEqual(0, filter_set.qs.count())

def test_provider_filter_with_providers(self):
path1 = PathFactory.create(provider='my_provider1')
path2 = PathFactory.create(provider='my_provider2')

filter_set = PathFilterSet()
filter_form = filter_set.form

self.assertIn('<option value="my_provider1">my_provider1</option>', filter_form.as_p())
self.assertIn('<option value="my_provider2">my_provider2</option>', filter_form.as_p())

self.assertIn(path1, filter_set.qs)
self.assertIn(path2, filter_set.qs)


class TrailFilterTest(CommonTest, AuthentFixturesTest):
factory = TrailFactory
filterset = TrailFilterSet

def test_provider_filter_without_provider(self):
filter_set = TrailFilterSet(data={})
filter_form = filter_set.form

self.assertTrue(filter_form.is_valid())
self.assertEqual(0, filter_set.qs.count())

def test_provider_filter_with_providers(self):
trail1 = TrailFactory.create(provider='my_provider1')
trail2 = TrailFactory.create(provider='my_provider2')

filter_set = TrailFilterSet()
filter_form = filter_set.form

self.assertIn('<option value="my_provider1">my_provider1</option>', filter_form.as_p())
self.assertIn('<option value="my_provider2">my_provider2</option>', filter_form.as_p())

self.assertIn(trail1, filter_set.qs)
self.assertIn(trail2, filter_set.qs)
Loading

0 comments on commit 2030c66

Please sign in to comment.