Skip to content

Commit f7a409f

Browse files
committed
implemented custom date and time range filter
1 parent 51b39fc commit f7a409f

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

django_filters/fields.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django import forms
22

3-
from django_filters.widgets import RangeWidget, LookupTypeWidget
3+
from django_filters.widgets import RangeWidget, LookupTypeWidget, DateRangeWidget, DateTimeRangeWidget
44

55
class RangeField(forms.MultiValueField):
66
widget = RangeWidget
@@ -32,3 +32,33 @@ def __init__(self, field, lookup_choices, *args, **kwargs):
3232

3333
def compress(self, data_list):
3434
return data_list
35+
36+
class DateRangeField(forms.MultiValueField):
37+
widget = DateRangeWidget
38+
39+
def __init__(self, *args, **kwargs):
40+
fields = (
41+
forms.DateField(),
42+
forms.DateField(),
43+
)
44+
super(DateRangeField, self).__init__(fields, *args, **kwargs)
45+
46+
def compress(self, data_list):
47+
if data_list:
48+
return slice(*data_list)
49+
return None
50+
51+
class DateTimeRangeField(forms.MultiValueField):
52+
widget = DateTimeRangeWidget
53+
54+
def __init__(self, *args, **kwargs):
55+
fields = (
56+
forms.DateTimeField(),
57+
forms.DateTimeField(),
58+
)
59+
super(DateTimeRangeField, self).__init__(fields, *args, **kwargs)
60+
61+
def compress(self, data_list):
62+
if data_list:
63+
return slice(*data_list)
64+
return None

django_filters/filters.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
from django.db.models.sql.constants import QUERY_TERMS
66
from django.utils.translation import ugettext_lazy as _
77

8-
from django_filters.fields import RangeField, LookupTypeField
8+
from django_filters.fields import RangeField, LookupTypeField, DateRangeField, DateTimeRangeField
99

1010
__all__ = [
1111
'Filter', 'CharFilter', 'BooleanFilter', 'ChoiceFilter',
1212
'MultipleChoiceFilter', 'DateFilter', 'DateTimeFilter', 'TimeFilter',
1313
'ModelChoiceFilter', 'ModelMultipleChoiceFilter', 'NumberFilter',
14-
'RangeFilter', 'DateRangeFilter', 'AllValuesFilter',
14+
'RangeFilter', 'DateRangeFilter', 'AllValuesFilter',
15+
'CustomDateRangeFilter', 'CustomDateTimeRangeFilter'
1516
]
1617

1718
LOOKUP_TYPES = sorted(QUERY_TERMS.keys())
@@ -153,6 +154,22 @@ def filter(self, qs, value):
153154
value = ''
154155
return self.options[value][1](qs, self.name)
155156

157+
class CustomDateRangeFilter(Filter):
158+
field_class = DateRangeField
159+
160+
def filter(self, qs, value):
161+
if value:
162+
return qs.filter(**{'%s__range' % self.name: (value.start, value.stop)})
163+
return qs
164+
165+
class CustomDateTimeRangeFilter(Filter):
166+
field_class = DateTimeRangeField
167+
168+
def filter(self, qs, value):
169+
if value:
170+
return qs.filter(**{'%s__range' % self.name: (value.start, value.stop)})
171+
return qs
172+
156173
class AllValuesFilter(ChoiceFilter):
157174
@property
158175
def field(self):

django_filters/widgets.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,29 @@ def decompress(self, value):
8181
if value is None:
8282
return [None, None]
8383
return value
84+
85+
class DateRangeWidget(forms.MultiWidget):
86+
def __init__(self, attrs=None):
87+
widgets = (forms.DateInput(attrs=attrs), forms.DateInput(attrs=attrs))
88+
super(DateRangeWidget, self).__init__(widgets, attrs)
89+
90+
def decompress(self, value):
91+
if value:
92+
return [value.start, value.stop]
93+
return [None, None]
94+
95+
def format_output(self, rendered_widgets):
96+
return u'-'.join(rendered_widgets)
97+
98+
class DateTimeRangeWidget(forms.MultiWidget):
99+
def __init__(self, attrs=None):
100+
widgets = (forms.DateTimeInput(attrs=attrs), forms.DateTimeInput(attrs=attrs))
101+
super(DateTimeRangeWidget, self).__init__(widgets, attrs)
102+
103+
def decompress(self, value):
104+
if value:
105+
return [value.start, value.stop]
106+
return [None, None]
107+
108+
def format_output(self, rendered_widgets):
109+
return u'-'.join(rendered_widgets)

0 commit comments

Comments
 (0)