views:

572

answers:

2

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.

+1  A: 

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)

)

Thanks krubo. This actually helped me.
maheshexp
+2  A: 

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?

fromClouds
Yeah you are right if I use it as a Date(). But I'm planning to use the entire timestamp as a VARCHAR. If you look into the code you might see that I'm reducing the tuples as a string. So, shouldnt be a problem.
maheshexp
+1 Django does primary keys automatically. You should only set your own primary key if there's an important reason for it.