1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 | import datetime
from django import newforms as forms
class DateDropdownWidget(forms.MultiWidget):
def __init__(self,attrs=None,year_range=None,month_range=None,day_range=None):
YEARS = year_range or range(2000,2021)
MONTHES = month_range or range(1,13)
DAYS = day_range or range(1,32)
years = map( lambda x: (x,x), YEARS )
months = map(lambda x:(x,x), MONTHES )
days = map( lambda x: (x,x), DAYS )
widgets = (
forms.Select(choices=years),
forms.Select(choices=months),
forms.Select(choices=days),
)
super(DateDropdownWidget, self).__init__(widgets, attrs)
def format_output(self,widgets):
format = "Year %s Month %s Day %s".decode('utf-8')
return format%(widgets[0],widgets[1],widgets[2])
def decompress(self,value):
if value:
return [value.year, value.month,value.day]
return [None,None,None]
class DateField(forms.MultiValueField):
widget = DateDropdownWidget
def __init__(self,*args,**kwargs):
fields = (
forms.IntegerField( required=True),
forms.IntegerField( required=True),
forms.IntegerField( required=True ),
)
super(DateField, self).__init__(fields, *args,**kwargs )
def compress(self,data_list):
EMPTY_VALUES = [None, '']
ERROR_EMPTY = "Fill the fields."
ERROR_INVALID = "Enter a valid date."
if data_list:
if filter(lambda x: x in EMPTY_VALUES, data_list):
raise forms.ValidationError(ERROR_EMPTY)
try:
return datetime.datetime(*map(lambda x:int(x),data_list))
except ValueError:
raise forms.ValidationError(ERROR_INVALID)
return None
|
Comments
While I'm sure this code is useful on a number of accounts, the coding style doesn't really make me cheer.
Why a list here? You could just as well have used a tuple.
PEP 8, which is what Django follows for the most of it, is violated on a number of accounts as well.
Sometimes you use a space after commas, sometimes (mostly) you don't, and you have 5 lambdas in 52 lines of code.
As for the
DateDropdownWidget.format_output, you could've done:The extra
tuplecall to ensure thatwidgetsis indeed a tuple.Duly note how it is fine to use
u""when you only use ASCII. Another solution is to set an explicit coding at the top of the file,Lastly, might I suggest using
xrangeinstead ofrange?xrangedoes not need to allocatenreferences to integers in memory while the range is still referenced, as it is a generator and generates on the fly.Other than that, I'm sure the code is really useful.
#
Hi i couldnt use it so i created a form :
class DateF(forms.Form): d=DateField()
And on the console :
In [48]: data={'d':[1,12,2004]}
In [49]: d=DateF(data)
In [50]: d.errors Out[50]: {'d': [u'This field is required.']}
Where is my error ?
#