Storing passages of time

One thing I need for VGMix is the ability to store the length of a song in a Django model. There are date and time features, but nothing for just a length of time, unrelated to any particular point in time. I did a bit of searching and found a ticket to add an IntervalField to Django, but no patches were provided.

So naturally, I decided to investigate and write a patch for it. The result is attached to that ticket, and does the job fairly well. It’s not quite finished yet, but there’s been some interest in this feature, so I thought I’d document what I’ve done so far.

Please note that I haven’t provided this separately yet, so if you want to try this out before it gets into trunk, you’ll have to copy the code out of the patch and put it into a module in your project and use it from there. Please don’t go patching your Django source.

Basically, this patch just adds a DurationField to Django, both for models and newforms. It validates user input and converts it to a Python timedelta object.

Models

Using DurationField in a model is as simple as anything else. Just include a line like the following in your model and enjoy the benefits:

class Song(models.Model):
    title = models.CharField(maxlength=255)
    length = models.DurationField()

This will store the value in the database the same way as a DecimalField, but this allows it to maintain all the precision that a timedelta supports. Unfortunately, the admin presents it the same as a DecimalField as well, since the existing admin is a bit difficult to extend in that way. So editing it in the admin will require entering values as the number of seconds to be saved.

If you’re using newforms-admin, it will use the newforms widget described below.

Forms

You can also use DurationField in any newforms form, by using the same code described above:

class Song(forms.Form):
    title = forms.CharField()
    length = forms.DurationField()

This will automatically use an improved widget, which presents the value as a set of input fields in the following format:

days, : : .

This is the same format timedelta uses when displaying its string equivalent, and seemed the most straightforward to me. The biggest downfall to the patch as it stands is that you must supply a value for each portion of the field. If you don’t need to include days, for instance, just supply a 0 instead. It’s unfortunate, and will be fixed in the future, but it’s not there yet.

Going forward

This will be improved and polished up in the near future, so things will get better. However, there’s no telling how long it will be before it’s ready to make it into Django proper. If I get it finished up fairly soon, I may make it available as a separate download for use until it gets in the main distribution.

Comments

  1. At 12:31 a.m. on Nov 4, 2007, Guan Yang said ...

    You might like to know that PostgreSQL has a data type for this, interval.

  2. At 2:37 a.m. on Nov 4, 2007, Anonymous said ...

    Sweet! I'm really looking forward to this being a regular feature. Thanks for your work.

  3. At 2:21 p.m. on Nov 4, 2007, Marty Alchin said ...

    @guan: Yes, I'm aware of PostgreSQL's interval data type, but using Decimal allows it to work in all backends that support decimals, which is all the ones Django supports. The only reason to fork for PostgreSQL is to have the database layer make the timedelta conversion (if it does). And that's just not worth it, when I already need to convert it manually for the other backends.

  4. At 1:13 p.m. on Nov 17, 2007, akaihola said ...

    Great feature! I would have needed this already in the spring of last year...

Speak up!


This particular article was posted on Saturday, November 3, 2007, and has received 4 comments.

It was preceeded by The future of dbsettings and followed by Django in JavaScript.

It contains the following links:

Archive

Categories

Powered by Django.