【问题标题】:Which django field should be used for a time counter? ACTUAL哪个 django 字段应该用于计时器?实际的
【发布时间】:2020-04-13 21:07:39
【问题描述】:

我需要模型中的一个字段来表示所需的工作时间。例如,默认值为 40 小时。我应该使用哪个字段?

更新

当我使用时:

required_work_hours = models.DurationField(_('Required work hours'), blank=True, null=True,
                                           default=timedelta(hours=40))

我得到一个值 1 16:00:00 而不是 40 小时

附:

我已经拥有start_timeend_time。我应该有一个可以与end_time - start_time比较的值

【问题讨论】:

  • 分辨率是多少?一小时?等一下?十分钟?
  • @WillemVanOnsem 1 小时

标签: django django-models


【解决方案1】:

使用像日期这样的整数,我觉得丢失了一些信息。

我会用work_start_timework_end_time 对其进行建模。您可以使用DateTimeField,设置默认值并在模型上添加一个计算字段,查看这两个日期来计算小时数。需要考虑的事情。

【讨论】:

  • 我已经有了start_timeend_time。我应该有一个值可以与end_time - start_time 进行比较
  • 您比较的工作时间值可能是您创建该员工时添加的值?即使在这种情况下,我也会小心,并检查人们工作的小时数是否会随着时间而改变。此外,40 小时作为标准正在慢慢改变。人们轮班工作,企业正在尝试每周工作 4 天。
  • 这不是在您创建该员工时添加的值。它必须是那个价值。在乌克兰以 40 小时为标准的情况不会很快改变:)
【解决方案2】:

如果您计划存储整个小时(而不是分钟、秒),则可以使用 PositiveSmallIntegerField。像大多数 Django ModelFields 一样,您可以设置一个默认值(我猜在您的情况下是 40)。

您也可以使用DurationField。它接受datetime.timedelta 值。因此,它可以存储天、小时、秒。

请参阅How should I use DurationField in my model? SO 条目以了解DurationField 的用法。

我已经有了start_timeend_time

好吧,在这种情况下:假设这两个字段都是DateTimeField 类型,那么end_time - start_time 应该给你datetime.timedelta 实例。然后可以将此datetime.timedelta 实例转换为小时数。

代码如下:

delta = end_time - start_time
hours = (delta.days * 24) + (delta.seconds // 3600)

【讨论】:

    【解决方案3】:

    您可以使用PositiveSmallIntegerField [Django-doc] 来存储小整数。 Django 保证最小范围是:

    类似于PositiveIntegerField,但只允许某个(依赖于数据库的)点下的值。 从 0 到 32767 的值在 Django 支持的所有数据库中都是安全的。

    因此可以表示每周的小时数,因为每周有 168 小时。 Furhtmore Django 将验证该数字是否为正数,这意味着如果您输入负数,它将在表单中引发错误。

    您可以进一步使用验证器来丰富它,例如:

    from django.core.validators import MaxValueValidator
    
    class MyModel(models.Model):
        hours = models.PositiveIntegerField(
            validators=[MaxValueValidator(168, 'There are only 168 hours a week.')],
            default=40
        )

    因此它将小时数存储为整数。这意味着您可以存储 39、40 或 41,但不能存储 40.5。

    对于一般持续时间,您可以使用DurationField [Django-doc]。这会将 Python 级别的值转换为 timedelta 对象,在数据库级别,它在 PostgreSQL 数据库上使用 interval,在 Oracle 上使用 INTERVAL DAY(9) TO SECOND(6),在其他数据库上,它将在窗帘后面使用bigint。然而,这样做的好处是,它将持续时间表示为 timedelta,这使得对 datetime 对象进行算术运算变得很方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-08
      • 2019-06-22
      • 1970-01-01
      • 2014-11-25
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多