Django:自定义时间戳字符串字段

0 投票
2 回答
1620 浏览
提问于 2025-04-15 12:11

我正在尝试创建一个自定义的时间戳字段。

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

用时间戳作为主键是否明智呢?如果你的数据库使用的是ISO 8601格式,或者任何一种以秒为最小时间单位的时间格式……总之,我想说的是,你没有办法保证,特别是如果这是一个面向网络的应用程序,两个记录会在最小时间间隔内被区分开。也就是说,如果最小的时间间隔是一秒,比如ISO 8601格式,如果你在同一秒内收到两个保存请求,就会出现错误。为什么不使用自动递增的整数作为主键,而把时间戳单独放在一个字段里呢?

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)

撰写回答