Creating a timedelta field.

132 views
Skip to first unread message

Roy Smith

unread,
Apr 1, 2013, 9:29:09 PM4/1/13
to mongoeng...@googlegroups.com
I've got a Document subclass which includes a duration field. Logically, it should be an instance of datetime.timedelta, but since there's no bson timedelta, we store the value as an integer (seconds).

What I'd like to do is create a field which looks like a timedelta to users of the model, but stores the value as an integer. What's the best way to go about doing that? Just do the conversion in post_init() and pre_save() hooks?

Or, should I subclass BaseField and invent my own TimeDeltaField? Looking at the implementation of DateTimeField in fields.py, this doesn't look terribly complicated, but maybe it's not a good idea to mess around under the covers that much?

--
Roy Smith
r...@panix.com

Brent Tubbs

unread,
Apr 2, 2013, 2:00:53 AM4/2/13
to mongoeng...@googlegroups.com
Writing custom fields is common practice in Django, which mongoengine more or less mimics.  See https://docs.djangoproject.com/en/dev/howto/custom-model-fields/.  I think these covers were meant to be messed around under.


--
You received this message because you are subscribed to the Google Groups "MongoEngine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongoengine-us...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Roy Smith

unread,
Apr 2, 2013, 11:07:49 AM4/2/13
to mongoeng...@googlegroups.com
On Apr 2, 2013, at 2:00 AM, Brent Tubbs wrote:

Writing custom fields is common practice in Django, which mongoengine more or less mimics.  See https://docs.djangoproject.com/en/dev/howto/custom-model-fields/.  I think these covers were meant to be messed around under.

Thanks.   This is what I ended up with.  Not quite done testing, but it seems to work.  I'm happy to donate it to back to the project if people think it's of sufficiently general value.  It uses total_seconds(), so won't work with Python 2.6 or earlier.

class TimedeltaField(BaseField):
    """A timedelta field.                                                                                        
                                                                                                                 
    Looks to the outside world like a datatime.timedelta, but stores                                             
    in the database as an integer (or float) number of seconds.                                                  
                                                                                                                 
    """
    def validate(self, value):
        if not isinstance(value, (timedelta, int, float)):
            self.error(u'cannot parse timedelta "%r"' % value)

    def to_mongo(self, value):
        return self.prepare_query_value(None, value)

    def to_python(self, value):
        return timedelta(seconds=value)

    def prepare_query_value(self, op, value):
        if value is None:
            return value
        if isinstance(value, timedelta):
            return value.total_seconds()
        if isinstance(value, (int, float)):
            return value







---
Roy Smith



Ross Lawley

unread,
Apr 8, 2013, 7:08:12 AM4/8/13
to mongoeng...@googlegroups.com
Hi,

Been on holiday, so late to the conversation - Roy that looks good.  There have been suggestions for a few niche field types, maybe adding a new repo for them might be good, with documentation and tests.

Would that be something you'd be interested in heading up Roy?

Ross


Roy Smith

unread,
Apr 8, 2013, 9:26:55 AM4/8/13
to mongoeng...@googlegroups.com, Ross Lawley
On Apr 8, 2013, at 7:08 AM, Ross Lawley wrote:

> Hi,
>
> Been on holiday, so late to the conversation - Roy that looks good. There have been suggestions for a few niche field types, maybe adding a new repo for them might be good, with documentation and tests.
>
> Would that be something you'd be interested in heading up Roy?
>
> Ross


Sure. We've gotten plenty of value out of mongoengine, it's time to give something back. Fill me in on the details of how you'd like that to work.

--
Roy Smith
r...@panix.com



Ross Lawley

unread,
Apr 11, 2013, 10:48:52 AM4/11/13
to Roy Smith, mongoeng...@googlegroups.com
Thats great news!

I've created https://github.com/MongoEngine/extras-mongoengine and added you to the repo admins.

Feel free to add the code there and once your happy I'll try and get some of the other field type authors to commit and contribute.

We use travis to test mongoengine and we can use the existing field test case style to get the test suite started, feel free to ping me if you want my help setting anything up - if needed I could set up the first demo field and travis tests.

Let me know what you think,

Ross

Roy Smith

unread,
Apr 11, 2013, 10:56:29 AM4/11/13
to mongoeng...@googlegroups.com
Cool.  I just got the github notice.  We do our work in hg, but I think I can figure out enough git to at least import the code into your repo :-)

I've never worked with Travis.  I assume that's a variation on the Hudson/Jenkins idea?


--
You received this message because you are subscribed to the Google Groups "MongoEngine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongoengine-us...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


---
Roy Smith



Reply all
Reply to author
Forward
0 new messages