Login

Drop down Datefield

Author:
lurker
Posted:
August 31, 2007
Language:
Python
Version:
.96
Score:
1 (after 5 ratings)

Simple drop-down date field for use.

You can specify date range by initiating new DateDropdownWidget.

Welcome comments!

 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

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

ludvig.ericson (on September 18, 2007):

While I'm sure this code is useful on a number of accounts, the coding style doesn't really make me cheer.

def decompress(self,value):
    if value:
        return [value.year, value.month,value.day]
    return [None,None,None]

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:

def format_output(self, widgets):
    return u"Year %s Month %s Day %s" % tuple(widgets)

The extra tuple call to ensure that widgets is 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,

# encoding: utf-8

Lastly, might I suggest using xrange instead of range? xrange does not need to allocate n references 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.

#

makkalot (on October 2, 2007):

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 ?

#

artur_mwaigaryan (on August 9, 2013):

thanks for the link @ dougal

#

Please login first before commenting.