MSW
MSW

Reputation: 62

Django : Timestamp string custom field

I'm trying to create a custom timestamp field.

class TimestampKey(models.CharField):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        import time

        kwargs['unique'] = True
        kwargs['max_length'] = 20
        kwargs['auto_created'] = True
        kwargs['editable']=False
        super(TimestampKey, self).__init__(*args, **kwargs)

    def to_python(self, value) :
        return value

    def get_db_prep_value(self, value) :
        try:
            import time
            t = time.localtime()
            value = reduce(lambda a,b:str(a)+str(b),t)
        except ValueError:
            value = {}

        return value


class Table1(models.Model):
       f = TimestampKey(primary_key=True)
       n = ....

It stores the value with appropriate timestamp in the db. But it doesnt populate the field 'f' in the object.

Eg:

t1 = Table1(n="some value")
t1.f -> blank

t1.save()

t1.f -> blank. 

This is the problem. Am I missing something so that it doesnt populate the filed? Please shed some light on this.

Thanks.

Upvotes: 0

Views: 1624

Answers (2)

fromClouds
fromClouds

Reputation: 305

Is it wise to use a timestamp as your primary key? If your database uses ISO 8601 or really any time format in which second is the smallest time interval... Well, anyway, my point is that you have no guarantee, especially if this is going to be a web-facing application that two entries are going to resolve within the minimum time interval. That is, if the smallest time interval is a second, as in ISO 8601, if you get two requests to save in the same second, you're going to get an error condition. Why not stick to automatically incrementing integer keys and just make the timestamp its own field?

Upvotes: 3

krubo
krubo

Reputation: 6416

The get_db_prep_value method only prepares a value for the database, but doesn't send the prepared value back to the Python object in any way. For that you would need the pre_save method, I think.

Fortunately, there's already an "auto_now" option on DateField and DateTimeField that does what you want, using pre_save. Try:

class Table1(models.Model):
    f = models.DateTimeField(auto_now=True)

(If you must write your own pre_save, look at how auto_now modifies the actual model instance in /django/db/models/fields/__init__.py on lines 486-492:

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:
        return super(DateField, self).pre_save(model_instance, add)

)

Upvotes: 1

Related Questions