Django timedelta custom model field (with full example)
by Subhranath Chunder
This intends to show a full working example of a django custom model field.
TimeDeltaField uses python object serialization or namely pickle, to store a datetime.timedelta type native python object on a database in the form of character data. This example implements only the must-have elements for it's working.
import datetime
import pickle
from django.db import models
class TimeDeltaField(models.Field):
"""Custom model field to store python native datetime.timedelta
object in database, in serialized form.
"""
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
# Set the max_length to something long enough to store the data
# in string format.
kwargs['max_length'] = 200
# Make sure the default specified is also serialized, else the
# objects own string representation would be used.
if 'default' in kwargs:
kwargs['default'] = pickle.dumps(kwargs['default'])
super(TimeDeltaField, self).__init__(*args, **kwargs)
def get_internal_type(self):
# Store the serialized data as the default 'CharField' type in
# the database.
return 'CharField'
def to_python(self, value):
if isinstance(value, basestring):
# De-Serialize into timedelta.
return pickle.loads(str(value))
return value
def get_prep_value(self, value):
# Serialize the object.
return pickle.dumps(value)
class MyModel(models.Model):
"""Dummy implementation of a model.
"""
timedelta = TimeDeltaField(default=datetime.timedelta(days=30))
def __unicode__(self):
return unicode(self.id)
This entitles us to use APIs such as:
# Creates a models instance with default value of timedelta.
MyModel.objects.create()
# Creates an instance with your own specified timedelta value.
MyModel.objects.create( \
timedelta=datetime.timedelta(datetime.timedelta(days=10, seconds=100))
)
This code has been written and tested in Django 1.4 pre-alpha version.
Comments
awesome blog, do you have twitter or facebook? i will bookmark this page thanks.
My blog:
rachat credit proprietaire rachat de credits
@aubrie: Yes, I do have. You can find the links on: http://scratch-blog.appspot.com/#links or http://www.subhranath.com/#links
There are many better ways to do this. e.g. https://bitbucket.org/schinckel/django-timedelta-field/ uses database native types to make it queryable.
@Thomas: Obviously, there must be better ways depending upon the purpose. For non-query purposes, this solution would be just simple and sound.