Login

SplitSelectDateTimeWidget

Author:
bradmontgomery
Posted:
November 19, 2008
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

This class extends MultiWidget to create a widget that consists of HTML select elements for Django's forms.DateTimeFields. This results in a select elements with options for month, day, year, hour, minute, second, and (if using the twelve_hr option) meridiem.

# Default usage of SplitSelectDateTimeWidget
class TimeForm(Form):
    dt = DateTimeField(widget=SplitSelectDateTimeWidget())

Another example hooks into the flexibility of the underlying Select Widgets:

class TimeForm(Form)
    dt = DateTimeField(widget=SplitSelectDateTimeWidget(hour_step=2, \
    minute_step=15, second_step=30, twelve_hr=True, years=[2008,2009,2010]))

The above example displays hours in increments of 2, minutes in increments of 15, and seconds in increments of 30. Likewise, only the years 2008, 2009,and 2010 are displayed in the years' options.

 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
class SplitSelectDateTimeWidget(MultiWidget):
    """
    MultiWidget = A widget that is composed of multiple widgets.

    This class combines SelectTimeWidget and SelectDateWidget so we have something 
    like SpliteDateTimeWidget (in django.forms.widgets), but with Select elements.
    """
    def __init__(self, attrs=None, hour_step=None, minute_step=None, second_step=None, twelve_hr=None, years=None):
        """ pass all these parameters to their respective widget constructors..."""
        widgets = (SelectDateWidget(attrs=attrs, years=years), SelectTimeWidget(attrs=attrs, hour_step=hour_step, minute_step=minute_step, second_step=second_step, twelve_hr=twelve_hr))
        super(SplitSelectDateTimeWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            return [value.date(), value.time().replace(microsecond=0)]
        return [None, None]

    def format_output(self, rendered_widgets):
        """
        Given a list of rendered widgets (as strings), it inserts an HTML
        linebreak between them.
        
        Returns a Unicode string representing the HTML for the whole lot.
        """
        rendered_widgets.insert(-1, '<br/>')
        return u''.join(rendered_widgets)

More like this

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

Comments

ramalho (on May 6, 2010):

Thanks for sharing a great snippet, Brad. BTW, in Python you almost never need to use backslashes to signal statement continuation. That is because within pairwise delimiters (){}[] and triple-quotes, Python does not consider the line ending a statement terminator. In particular, all of the \'s in your code above may be removed.

#

bradmontgomery (on May 21, 2010):

Thanks for the feedback. I've updated the snippet removing the \'s and cleaned up the docstrings a bit.

#

Please login first before commenting.