2009-06-12 2 views
0

Я пытаюсь создать настраиваемое поле метки времени.Django: Timestamp string пользовательское поле

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 = .... 

Он сохраняет значение с соответствующей меткой времени в db. Но он не заполняет поле 'f' в объекте.

Например:

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

t1.save() 

t1.f -> blank. 

Это проблема. Я что-то упустил, чтобы он не заполнил поданную? Прошу пролить свет на это.

Спасибо.

ответ

1

Метод get_db_prep_value только готовит значение для базы данных, но не отправляет готовое значение обратно на объект Python. Для этого вам понадобится метод pre_save, я думаю.

К счастью, в DateField и DateTimeField уже есть опция «auto_now», которая делает то, что вы хотите, используя pre_save. Попробуйте:

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

(Если вы должны написать свой собственный pre_save, посмотрите на то, как auto_now изменяет фактический экземпляр модели в /django/db/models/fields/__init__.py на линиях 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) 

)

+0

Спасибо, krubo. Это действительно помогло мне. – MSW

3

Разумно использовать временную метку в качестве основного ключа? Если ваша база данных использует ISO 8601 или действительно любой формат времени, в котором вторая является наименьшим временным интервалом ... Ну, во всяком случае, я хочу сказать, что у вас нет гарантии, особенно если это будет приложение с веб-интерфейсом, в котором две записи будут разрешаться в течение минимального интервала времени. То есть, если наименьший интервал времени является вторым, как в ISO 8601, если вы получите два запроса на сохранение за одну секунду, вы получите условие ошибки. Почему бы не придерживаться автоматического увеличения целых ключей и просто сделать timestamp своим полем?

+0

Да, вы правы, если я использую его как Date(). Но я планирую использовать всю метку времени как VARCHAR. Если вы посмотрите на код, вы можете увидеть, что я сокращаю кортежи как строку. Таким образом, не должно быть проблемой. – MSW

+0

+1 Django делает первичные ключи автоматически. Вы должны установить свой собственный первичный ключ, если для этого есть важная причина. – krubo

Смежные вопросы