【问题标题】:How to put timedelta in django model?如何将 timedelta 放入 django 模型中?
【发布时间】:2010-10-22 13:29:19
【问题描述】:

通过inspectdb,我能够从postgres 获取一个“interval”字段到django。在 Django 中,它是一个 TextField。我检索到的对象确实是 timedelta 对象!

现在我想将这个 timedelta 对象放入一个新模型中。最好的方法是什么?因为将 timedelta 放入 TextField 会导致对象的 str 版本...

【问题讨论】:

  • 从 Django 1.8 开始你可以使用 DurationField。

标签: django


【解决方案1】:

here 解释了一种解决方法。如果您使用的是 Postgresql,那么将 F 表达式的结果与 timedelta 相乘即可解决问题。例如,如果您在分钟内有一个start_time 和一个duration,您可以像这样计算end_time

YourModel.objects.annotate(
    end_time=ExpressionWrapper(F('start_time') + timedelta(minutes=1) * F('duration'), output_field=DateTimeField())
)

【讨论】:

    【解决方案2】:

    从 Django 1.8 开始,您可以使用DurationField

    【讨论】:

    【解决方案3】:

    把它放在那里可能是解决这个问题的另一种方法。 首先安装这个库:https://pypi.python.org/pypi/django-timedeltafield

    然后:

    import timedelta
    
    class ModelWithTimeDelta(models.Model):
        timedeltafield = timedelta.fields.TimedeltaField()
    

    在管理员中,您将被要求在字段中输入以下格式的数据:3 天 4 小时 2 分钟

    【讨论】:

    • 我更喜欢 Django 1.7 的这个解决方案,因为它在 pip repo 中,而不是外部源。
    【解决方案4】:

    您可以轻松地将 timedelta 标准化为以天或秒为单位的单个浮点数。

    这是“归一化到天”的版本。

    float(timedelta.days) + float(timedelta.seconds) / float(86400)
    

    您可以轻松地将浮点数转换为时间增量。

    >>> datetime.timedelta(2.5)
    datetime.timedelta(2, 43200)
    

    因此,将您的 timedelta 存储为浮点数。

    这是“归一化到秒”的版本。

    timedelta.days*86400+timedelta.seconds
    

    这是相反的(使用秒)

    datetime.timedelta( someSeconds/86400 )
    

    【讨论】:

    • 当然你的意思是 float(timedelta.days) + float(timedelta.seconds)/float(86400) ...但它有效!
    • @Jack Ha:感谢您发现问题。
    • timedelta.days+timedelta.seconds/86400.0
    • 从 python 2.7 开始,您可以使用timedelta.total_seconds 方法将其标准化为秒。
    【解决方案5】:

    有一张可以追溯到 2006 年 7 月的罚单与此相关: https://code.djangoproject.com/ticket/2443

    编写了几个补丁,但其中一个已提交到项目中: https://github.com/johnpaulett/django-durationfield

    与这里的所有其他答案相比,这个项目是成熟的,并且会被合并到核心,除了它的包含目前被认为是“臃肿”。

    就个人而言,我刚刚尝试了一堆解决方案,这是一个效果很好的解决方案。

    from django.db import models
    from durationfield.db.models.fields.duration import DurationField
    
    class Event(models.Model):
        start = models.DateTimeField()
        duration = DurationField()
    
        @property
        def finish(self):
            return self.start + self.duration
    

    结果:

    $ evt = Event.objects.create(start=datetime.datetime.now(), duration='1 week')
    $ evt.finish
    Out[]: datetime.datetime(2013, 6, 13, 5, 29, 29, 404753)
    

    在管理员中:

    更改事件

    时长:7 days, 0:00:00

    【讨论】:

    【解决方案6】:

    首先,定义你的模型:

    class TimeModel(models.Model):
        time = models.FloatField()
    

    存储一个 timedelta 对象:

    # td is a timedelta object
    TimeModel.objects.create(time=td.total_seconds())
    

    从数据库中取出 timedelta 对象:

    # Assume the previously created TimeModel object has an id of 1
    td = timedelta(seconds=TimeModel.objects.get(id=1).time)
    

    注意:我在此示例中使用的是 Python 2.7。

    【讨论】:

    • 在低于2.7版本的python上可以使用公式:total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
    • 这很棒。感谢您既简洁又透彻
    【解决方案7】:

    【讨论】:

    • 在存储库中:检查。作品:检查。感谢分享。
    【解决方案8】:

    对于 PostgreSQL,请在此处使用 django-pgsql-interval-field:http://code.google.com/p/django-pgsql-interval-field/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      • 2020-03-05
      • 1970-01-01
      • 2011-09-26
      • 2012-06-29
      • 2018-02-14
      相关资源
      最近更新 更多