Django: настраиваемое поле строки метки времени - PullRequest
0 голосов
/ 12 июня 2009

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

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

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

Например:

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

t1.save()

t1.f -> blank. 

Это проблема. Я что-то упустил, чтобы он не заполнял поле? Пожалуйста, пролите немного света на это.

Спасибо.

Ответы [ 2 ]

3 голосов
/ 12 июня 2009

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

1 голос
/ 12 июня 2009

Метод 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)

)

...