class TimeWidget(forms.MultiWidget): """Input accurate timing. IntegerFields for hours, minutes, seconds, milliseconds.""" NUM_FIELDS = 4 # Hours, Minutes, Seconds, Milliseconds def __init__(self, attrs=None): widgets = [forms.TextInput()] * self.NUM_FIELDS super(TimeWidget, self).__init__(widgets, attrs) def format_output(self, widgets): widgets.insert(1, ' : ') widgets.insert(3, ' : ') widgets.insert(5, ' . ') return mark_safe(''.join(widgets)) def decompress(self, value): if value: return ('%d' % (value/3600), '%02d' % (value%3600/60), '%02d' % (value%3600%60), '%03d' % (value%1*1000)) return [None] * self.NUM_FIELDS class TimeField(forms.MultiValueField): """Input accurate timing. Interface with models.DecimalField for great success.""" LABELS = ['Hours', 'Minutes', 'Seconds', 'Milliseconds'] SECONDS = [ 60*60, 60, 1, 0.001] widget = TimeWidget() def __init__(self, *args, **kwargs): fields = [forms.CharField(label=label) for label in self.LABELS] super(TimeField, self).__init__(fields, *args, **kwargs) def compress(self, value): if value: from operator import add, mul return str(reduce(add, map(lambda x: mul(*x), zip(map(float, value), self.SECONDS)))) return None