From f25a7a48bd51bb50df2f416a45fe92a9590cbbbb Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Tue, 11 Apr 2017 14:07:52 -0400 Subject: [PATCH] Update {Range,LookupType}Widgets to use suffixes --- django_filters/fields.py | 5 +++- django_filters/widgets.py | 11 +++++++++ docs/ref/filters.txt | 30 +++++++++++----------- tests/test_fields.py | 8 +++--- tests/test_filtering.py | 52 +++++++++++++++++++-------------------- tests/test_widgets.py | 27 ++++++++++---------- 6 files changed, 73 insertions(+), 60 deletions(-) diff --git a/django_filters/fields.py b/django_filters/fields.py index 160f41928..2fe97ff0e 100644 --- a/django_filters/fields.py +++ b/django_filters/fields.py @@ -11,7 +11,7 @@ from django.utils.translation import ugettext_lazy as _ from .utils import handle_timezone -from .widgets import RangeWidget, LookupTypeWidget, CSVWidget, BaseCSVWidget +from .widgets import RangeWidget, DateRangeWidget, LookupTypeWidget, CSVWidget, BaseCSVWidget class RangeField(forms.MultiValueField): @@ -31,6 +31,7 @@ def compress(self, data_list): class DateRangeField(RangeField): + widget = DateRangeWidget def __init__(self, *args, **kwargs): fields = ( @@ -56,6 +57,7 @@ def compress(self, data_list): class DateTimeRangeField(RangeField): + widget = DateRangeWidget def __init__(self, *args, **kwargs): fields = ( @@ -65,6 +67,7 @@ def __init__(self, *args, **kwargs): class TimeRangeField(RangeField): + widget = DateRangeWidget def __init__(self, *args, **kwargs): fields = ( diff --git a/django_filters/widgets.py b/django_filters/widgets.py index 7d1e086bf..c600c4dcf 100644 --- a/django_filters/widgets.py +++ b/django_filters/widgets.py @@ -148,6 +148,7 @@ def decompress(self, value): class RangeWidget(forms.MultiWidget): template_name = 'django_filters/widgets/multiwidget.html' + suffixes = ['min', 'max'] def __init__(self, attrs=None): widgets = (forms.TextInput, forms.TextInput) @@ -155,6 +156,10 @@ def __init__(self, attrs=None): def format_output(self, rendered_widgets): # Method was removed in Django 1.11. + rendered_widgets = [ + self.replace_name(output, i) + for i, output in enumerate(rendered_widgets) + ] return '-'.join(rendered_widgets) def decompress(self, value): @@ -163,7 +168,13 @@ def decompress(self, value): return [None, None] +class DateRangeWidget(RangeWidget): + suffixes = ['after', 'before'] + + class LookupTypeWidget(forms.MultiWidget): + suffixes = [None, 'lookup'] + def decompress(self, value): if value is None: return [None, None] diff --git a/docs/ref/filters.txt b/docs/ref/filters.txt index 1264c1086..153b179db 100644 --- a/docs/ref/filters.txt +++ b/docs/ref/filters.txt @@ -463,13 +463,13 @@ Filters where a value is between two numerical values, or greater than a minimum qs = Book.objects.all().order_by('title') # Range: Books between 5€ and 15€ - f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) + f = F({'price_min': '5', 'price_max': '15'}, queryset=qs) # Min-Only: Books costing more the 11€ - f = F({'price_0': '11'}, queryset=qs) + f = F({'price_min': '11'}, queryset=qs) # Max-Only: Books costing less than 19€ - f = F({'price_1': '19'}, queryset=qs) + f = F({'price_max': '19'}, queryset=qs) ``DateRangeFilter`` @@ -497,13 +497,13 @@ Example of using the ``DateField`` field:: fields = ['date'] # Range: Comments added between 2016-01-01 and 2016-02-01 - f = F({'date_0': '2016-01-01', 'date_1': '2016-02-01'}) + f = F({'date_after': '2016-01-01', 'date_before': '2016-02-01'}) # Min-Only: Comments added after 2016-01-01 - f = F({'date_0': '2016-01-01'}) + f = F({'date_after': '2016-01-01'}) # Max-Only: Comments added before 2016-02-01 - f = F({'date_1': '2016-02-01'}) + f = F({'date_before': '2016-02-01'}) .. note:: When filtering ranges that occurs on DST transition dates ``DateFromToRangeFilter`` will use the first valid hour of the day for start datetime and the last valid hour of the day for end datetime. @@ -530,15 +530,15 @@ Example of using the ``DateTimeField`` field:: Article.objects.create(published='2016-02-10 12:00') # Range: Articles published between 2016-01-01 and 2016-02-01 - f = F({'published_0': '2016-01-01', 'published_1': '2016-02-01'}) + f = F({'published_after': '2016-01-01', 'published_before': '2016-02-01'}) assert len(f.qs) == 2 # Min-Only: Articles published after 2016-01-01 - f = F({'published_0': '2016-01-01'}) + f = F({'published_after': '2016-01-01'}) assert len(f.qs) == 3 # Max-Only: Articles published before 2016-02-01 - f = F({'published_1': '2016-02-01'}) + f = F({'published_before': '2016-02-01'}) assert len(f.qs) == 2 ``DateTimeFromToRangeFilter`` @@ -563,15 +563,15 @@ Example:: Article.objects.create(published='2016-01-02 8:00') # Range: Articles published 2016-01-01 between 8:00 and 10:00 - f = F({'published_0': '2016-01-01 8:00', 'published_1': '2016-01-01 10:00'}) + f = F({'published_after': '2016-01-01 8:00', 'published_before': '2016-01-01 10:00'}) assert len(f.qs) == 2 # Min-Only: Articles published after 2016-01-01 8:00 - f = F({'published_0': '2016-01-01 8:00'}) + f = F({'published_after': '2016-01-01 8:00'}) assert len(f.qs) == 3 # Max-Only: Articles published before 2016-01-01 10:00 - f = F({'published_1': '2016-01-01 10:00'}) + f = F({'published_before': '2016-01-01 10:00'}) assert len(f.qs) == 2 ``TimeRangeFilter`` @@ -593,13 +593,13 @@ Example:: fields = ['time'] # Range: Comments added between 8:00 and 10:00 - f = F({'time_0': '8:00', 'time_1': '10:00'}) + f = F({'time_after': '8:00', 'time_before': '10:00'}) # Min-Only: Comments added after 8:00 - f = F({'time_0': '8:00'}) + f = F({'time_after': '8:00'}) # Max-Only: Comments added before 10:00 - f = F({'time_1': '10:00'}) + f = F({'time_before': '10:00'}) ``AllValuesFilter`` ~~~~~~~~~~~~~~~~~~~ diff --git a/tests/test_fields.py b/tests/test_fields.py index 5ffc70712..712494dfa 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -118,14 +118,14 @@ def test_render_used_html5(self): inner = forms.DecimalField() f = LookupTypeField(inner, [('gt', 'gt'), ('lt', 'lt')]) self.assertHTMLEqual(f.widget.render('price', ''), """ - - + """) self.assertHTMLEqual(f.widget.render('price', ['abc', 'lt']), """ - - + """) diff --git a/tests/test_filtering.py b/tests/test_filtering.py index 62b21f768..9e7a17ab4 100644 --- a/tests/test_filtering.py +++ b/tests/test_filtering.py @@ -675,11 +675,11 @@ class Meta: fields = ['price'] qs = Book.objects.all() - f = F({'price_0': '15', 'price_1': 'lt'}, queryset=qs) + f = F({'price': '15', 'price_lookup': 'lt'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title) - f = F({'price_0': '15', 'price_1': 'lt'}) + f = F({'price': '15', 'price_lookup': 'lt'}) self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title) - f = F({'price_0': '', 'price_1': 'lt'}) + f = F({'price': '', 'price_lookup': 'lt'}) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Rainbow Six', 'Snowcrash'], lambda o: o.title, ordered=False) @@ -691,7 +691,7 @@ class Meta: model = Book fields = ['price'] - f = F({'price_0': '15'}) + f = F({'price': '15'}) self.assertQuerysetEqual(f.qs, ['Rainbow Six'], lambda o: o.title) @@ -722,29 +722,29 @@ class Meta: self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Free Book', 'Rainbow Six', 'Refund', 'Snowcrash'], lambda o: o.title) - f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) + f = F({'price_min': '5', 'price_max': '15'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Rainbow Six'], lambda o: o.title) - f = F({'price_0': '11'}, queryset=qs) + f = F({'price_min': '11'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Rainbow Six', 'Snowcrash'], lambda o: o.title) - f = F({'price_1': '19'}, queryset=qs) + f = F({'price_max': '19'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Free Book', 'Rainbow Six', 'Refund'], lambda o: o.title) - f = F({'price_0': '0', 'price_1': '12'}, queryset=qs) + f = F({'price_min': '0', 'price_max': '12'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Free Book'], lambda o: o.title) - f = F({'price_0': '-11', 'price_1': '0'}, queryset=qs) + f = F({'price_min': '-11', 'price_max': '0'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Free Book', 'Refund'], lambda o: o.title) - f = F({'price_0': '0', 'price_1': '0'}, queryset=qs) + f = F({'price_min': '0', 'price_max': '0'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Free Book'], lambda o: o.title) @@ -847,8 +847,8 @@ class Meta: fields = ['date'] results = F(data={ - 'published_0': '2016-01-02', - 'published_1': '2016-01-03'}) + 'published_after': '2016-01-02', + 'published_before': '2016-01-03'}) self.assertEqual(len(results.qs), 3) def test_filtering_ignores_time(self): @@ -870,8 +870,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2016-01-02', - 'published_1': '2016-01-03'}) + 'published_after': '2016-01-02', + 'published_before': '2016-01-03'}) self.assertEqual(len(results.qs), 3) @unittest.skipIf(django.VERSION < (1, 9), 'version doesnt supports is_dst parameter for make_aware') @@ -891,8 +891,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2017-10-15', - 'published_1': '2017-10-15'}) + 'published_after': '2017-10-15', + 'published_before': '2017-10-15'}) self.assertEqual(len(results.qs), 2) @unittest.skipIf(django.VERSION < (1, 9), 'version doesnt supports is_dst parameter for make_aware') @@ -912,8 +912,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2017-02-18', - 'published_1': '2017-02-18'}) + 'published_after': '2017-02-18', + 'published_before': '2017-02-18'}) self.assertEqual(len(results.qs), 2) @unittest.skipIf(django.VERSION < (1, 9), 'version doesnt supports is_dst parameter for make_aware') @@ -934,8 +934,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2017-3-26', - 'published_1': '2017-3-26'}) + 'published_after': '2017-3-26', + 'published_before': '2017-3-26'}) self.assertEqual(len(results.qs), 3) @unittest.skipIf(django.VERSION < (1, 9), 'version doesnt supports is_dst parameter for make_aware') @@ -956,8 +956,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2017-10-29', - 'published_1': '2017-10-29'}) + 'published_after': '2017-10-29', + 'published_before': '2017-10-29'}) self.assertEqual(len(results.qs), 3) @@ -982,8 +982,8 @@ class Meta: fields = ['published'] results = F(data={ - 'published_0': '2016-01-02 10:00', - 'published_1': '2016-01-03 19:00'}) + 'published_after': '2016-01-02 10:00', + 'published_before': '2016-01-03 19:00'}) self.assertEqual(len(results.qs), 2) @@ -1006,8 +1006,8 @@ class Meta: fields = ['time'] results = F(data={ - 'time_0': '8:00', - 'time_1': '10:00'}) + 'time_after': '8:00', + 'time_before': '10:00'}) self.assertEqual(len(results.qs), 2) diff --git a/tests/test_widgets.py b/tests/test_widgets.py index dbfc2a342..3b486fac1 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -23,22 +23,22 @@ def test_widget_render(self): widgets = [TextInput(), Select(choices=(('a', 'a'), ('b', 'b')))] w = LookupTypeWidget(widgets) self.assertHTMLEqual(w.render('price', ''), """ - - + """) self.assertHTMLEqual(w.render('price', None), """ - - + """) self.assertHTMLEqual(w.render('price', ['2', 'a']), """ - - + """) @@ -192,27 +192,26 @@ def test_widget(self): w = RangeWidget() self.assertEqual(len(w.widgets), 2) self.assertHTMLEqual(w.render('price', ''), """ - + - - """) + """) self.assertHTMLEqual(w.render('price', slice(5.99, 9.99)), """ - + - - """) + """) def test_widget_attributes(self): w = RangeWidget(attrs={'type': 'date'}) self.assertEqual(len(w.widgets), 2) self.assertHTMLEqual(w.render('date', ''), """ - + - - """) + """) class BooleanWidgetTests(TestCase): - """ - """ + def test_widget_render(self): w = BooleanWidget() self.assertHTMLEqual(w.render('price', ''), """