Skip to content

Instantly share code, notes, and snippets.

@litchfield
Created April 24, 2012 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save litchfield/2476551 to your computer and use it in GitHub Desktop.
Save litchfield/2476551 to your computer and use it in GitHub Desktop.
Django DurationField
from django import forms
from django.db import models
def split_duration(value):
if value:
return ( '%02d' % (value // 3600),
'%02d' % ((value % 3600) // 60),
'%02d' % (value % 60),
)
return ('00', '00', '00')
class DurationWidget(forms.widgets.MultiWidget):
def __init__(self, attrs=None):
defaults = {'style': 'width: 2em'}
if attrs:
defaults.update(attrs)
widgets = [ forms.TextInput(attrs=defaults) ] * 3
super(DurationWidget, self).__init__(widgets, defaults)
def decompress(self, value):
return split_duration(value)
def format_output(self, rendered_widgets):
return u' : '.join(rendered_widgets)
class DurationFormField(forms.MultiValueField):
widget = DurationWidget
def __init__(self, fields=None, *args, **kwargs):
fields = [ forms.IntegerField(min_value=0, max_value=59) ] * 3
super(DurationFormField, self).__init__(fields, *args, **kwargs)
def compress(self, data_list):
if not data_list:
return None
duration = 0
for i, value in enumerate(data_list):
if value in forms.fields.EMPTY_VALUES:
continue
duration += value * (60 ** (2-i))
return duration
class Duration(int):
def __unicode__(self):
return ':'.join(split_duration(self))
class DurationField(models.Field):
__metaclass__ = models.SubfieldBase
def db_type(self):
return 'int'
def formfield(self, **kwargs):
defaults = {'form_class': DurationFormField}
defaults.update(kwargs)
return super(DurationField, self).formfield(**defaults)
def to_python(self, value):
if isinstance(value, Duration):
return value
try:
return Duration(value)
except ValueError:
return value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment