Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - make datetimefield accept unix timestamp

i'd like to make the DateTimefield of models accept unix timestamp (in seconds) values.

I found this but the acepted solution doesn't work?
unixtimestamp input in DataTimeField

i.e. i don't see how adding '%s' as an input format will work, especially when the code for to_python() of the standard datetime field doesn't include any logic for handling unix timestamps.

If there is a setting that allows me to do this great.
Otherwise, what I think i want is to subclass DateTimeField and somehow automatically convert the int to a datetime object when i set the value. I want to do this before saving instead of overriding save() because i want consistency when retrieving the value of this field. i.e. when I take the value out, I don't want to worry about if i have a datetime object or an int regardless of if the instance has been saved or not.

I looked at source of django.db.models.fields and it's not apparent to me.

like image 326
w-- Avatar asked Aug 24 '15 09:08

w--


2 Answers

The pip package django-unixdatetimefield provides a UnixDateTimeField field that you can use for this out of the box (https://pypi.python.org/pypi/django-unixdatetimefield/).

Example model:

from django_unixdatetimefield import UnixDateTimeField

class MyModel(models.Model):
    created_at = UnixDateTimeField()

Python ORM query:

>>> m = MyModel()
>>> m.created_at = datetime.datetime(2015, 2, 21, 19, 38, 32, 209148)
>>> m.save()

Database:

sqlite> select created_at from mymodel;
1426967129

Here's the source code if interested - https://github.com/Niklas9/django-unixdatetimefield.

Disclaimer: I'm the author of this pip package.

like image 192
Niklas9 Avatar answered Nov 09 '22 01:11

Niklas9


Using UNIX timestamp as values for DateTimeField should probably come with Django by default. Django’s introspection is really powerful but makes things less obvious than desirable, especially in the context of Python code.

You can achieve it by subclassing DateTimeField and overriding the pre_save method.

from django.db import models
from datetime import datetime

from django.db.models.fields import DateTimeField

class UCDateTimeField(DateTimeField):

    def pre_save(self, model_instance, add):
        if self.auto_now or (self.auto_now_add and add):
            value = datetime.datetime.now()
            setattr(model_instance, self.attname, value)
            return value
        else:
            value = getattr(model_instance, self.attname)
            if not isinstance(value, datetime):
                # assume that the value is a timestamp if it is not a datetime
                value = datetime.fromtimestamp(int(value))
                # an exception might be better than an assumption
                setattr(model_instance, self.attname, value)
            return super(UCDateTimeField, self).pre_save(model_instance, add)


class Event(models.Model):
    date = UCDateTimeField()
like image 41
Ben Beirut Avatar answered Nov 09 '22 00:11

Ben Beirut