From 2850d34be7672c11cf6585bca3ba2e8a8af05fbf Mon Sep 17 00:00:00 2001 From: basti <12233784+sebastianseitz@users.noreply.github.com> Date: Tue, 29 Sep 2020 17:20:31 +0200 Subject: [PATCH 1/4] make default MaxValue an integer, provide option to set default per filter instance --- django_filters/filters.py | 7 ++++++- tests/test_forms.py | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/django_filters/filters.py b/django_filters/filters.py index 8190af82e..bc2b7a5d5 100644 --- a/django_filters/filters.py +++ b/django_filters/filters.py @@ -358,11 +358,16 @@ class ModelMultipleChoiceFilter(QuerySetRequestMixin, MultipleChoiceFilter): class NumberFilter(Filter): field_class = forms.DecimalField + def __init__(self, *args, **kwargs): + self.max_value = kwargs.get('max_value', int(1e50)) + super().__init__(*args, **kwargs) + def get_max_validator(self): """ Return a MaxValueValidator for the field, or None to disable. """ - return MaxValueValidator(1e50) + if self.max_value is not None: + return MaxValueValidator(self.max_value) @property def field(self): diff --git a/tests/test_forms.py b/tests/test_forms.py index 568d7482a..1dc046693 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -267,5 +267,7 @@ class Meta: self.assertFalse(f.is_valid()) self.assertEqual( f.errors, - {'average_rating': ['Ensure this value is less than or equal to 1e+50.']} + {'average_rating': [ + f'Ensure this value is less than or equal to {int(1e+50)}.' + ]} ) From bbd21d339e561f01afb659eca47da1bb10efa50e Mon Sep 17 00:00:00 2001 From: basti <12233784+sebastianseitz@users.noreply.github.com> Date: Tue, 29 Sep 2020 17:24:32 +0200 Subject: [PATCH 2/4] make sure tests succeed also on python < 3.6 --- tests/test_forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_forms.py b/tests/test_forms.py index 1dc046693..e018250fc 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -268,6 +268,6 @@ class Meta: self.assertEqual( f.errors, {'average_rating': [ - f'Ensure this value is less than or equal to {int(1e+50)}.' + 'Ensure this value is less than or equal to %d.' % int(1e50) ]} ) From 584d1aa07541d91b9676921ad6ad1a6764099b43 Mon Sep 17 00:00:00 2001 From: basti <12233784+sebastianseitz@users.noreply.github.com> Date: Wed, 30 Sep 2020 09:08:03 +0200 Subject: [PATCH 3/4] remove kwarg from NumberFilter again --- django_filters/filters.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/django_filters/filters.py b/django_filters/filters.py index bc2b7a5d5..c2e400811 100644 --- a/django_filters/filters.py +++ b/django_filters/filters.py @@ -358,16 +358,11 @@ class ModelMultipleChoiceFilter(QuerySetRequestMixin, MultipleChoiceFilter): class NumberFilter(Filter): field_class = forms.DecimalField - def __init__(self, *args, **kwargs): - self.max_value = kwargs.get('max_value', int(1e50)) - super().__init__(*args, **kwargs) - def get_max_validator(self): """ Return a MaxValueValidator for the field, or None to disable. """ - if self.max_value is not None: - return MaxValueValidator(self.max_value) + return MaxValueValidator(int(1e50)) @property def field(self): From 877283b3de65c3d108651152a5364f1a07aff874 Mon Sep 17 00:00:00 2001 From: basti <12233784+sebastianseitz@users.noreply.github.com> Date: Wed, 30 Sep 2020 09:13:15 +0200 Subject: [PATCH 4/4] test-case for float-operation --- tests/test_forms.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test_forms.py b/tests/test_forms.py index e018250fc..51c5fe4fb 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -1,3 +1,5 @@ +from decimal import FloatOperation, getcontext + from django import forms from django.test import TestCase, override_settings @@ -271,3 +273,22 @@ class Meta: 'Ensure this value is less than or equal to %d.' % int(1e50) ]} ) + + + def test_number_filter_max_value_validation_no_float(self): + class F(FilterSet): + class Meta: + model = Book + fields = ['average_rating'] + + ctx = getcontext() + ctx.traps[FloatOperation] = True + f = F({'average_rating': '1E1001'}) + self.assertTrue(f.is_bound) + self.assertFalse(f.is_valid()) + self.assertEqual( + f.errors, + {'average_rating': [ + 'Ensure this value is less than or equal to %d.' % int(1e50) + ]} + )