【问题标题】:'datetime.date' object has no attribute 'days' error while using timedelta'datetime.date' 对象在使用 timedelta 时没有属性 'days' 错误
【发布时间】:2020-01-25 12:45:39
【问题描述】:

在这里,我正在编写属性方法来显示剩余休假天数和总休假天数。总休假天数工作正常,但 def leave_remaining_days(self) 这不起作用。 我去这个错误

'datetime.date' 对象没有属性'days'

这里的问题是在返回天数 return leave_remaining.days 时,但是当我返回 return leave_remaining 时,它就可以工作了。

这里如何计算剩余休假天数?

仅当leave.is_accepted 为真时,我才想计算剩余天数。

我想将1 的天数每天减少到end_day,直到

datetime.date.today() == self.end_day.

编辑:为此,我使用了 celery,但这也不起作用。最初检查它是否有效,我在周期性任务中设置了 minutes=1,但它不起作用。

models.py

class Leave(models.Model):
    staff = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='staff')
    sub = models.CharField(max_length=300)
    msg = models.TextField()
    start_day = models.DateField()
    end_day = models.DateField()
    is_accepted = models.BooleanField(default=False)
    is_rejected = models.BooleanField(default=False)

    @property
    def leave_days(self):
        diff = self.end_day - self.start_day
        return diff.days

    @property
    def leave_remaining_days(self):
        if self.is_accepted and not datetime.date.today() > self.end_day:
            leave_remaining = self.end_day - datetime.timedelta(days=1)
            return leave_remaining.days

#changes
from celery.schedules import crontab
from celery.task import periodic_task
@property
@periodic_task(run_every=crontab(minute=1))
def leave_remaining_day(self):
    if self.is_accepted and not datetime.date.today() > self.end_day:
        leave_remaining = self.leave_days - 1
        return leave_remaining

【问题讨论】:

  • 这是date 不是timedelta...
  • 我怎样才能减少日期1然后@WillemVanOnsem?

标签: python django datetime django-models celery


【解决方案1】:

您收到此错误的原因是因为从date 中减去timedelta 会得到date

date 没有days 属性(您可以通过创建一个属性并在其上调用dir(...) 或检查documentation 来检查)。

在旁注中,如果您希望 leave_remaining_days 返回距离 Leave 结束还剩多少天,那么您应该执行以下操作:

@property
    def leave_remaining_days(self):
        if self.is_accepted and not datetime.date.today() > self.end_day:
            delta = self.end_day - datetime.date.today()
            return delta.days

由于您要存储start_dayend_day,我不确定您是否需要每天减少任何内容。你也许可以检查一下我上面写的属性。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,那么在您的代码中:

    leave_remaining = self.end_day - datetime.timedelta(days=1)
    return leave_remaining.days
    

    leave_remainingdatetime.date,比self.end_day 早1 天,我认为这是您想要的;像这样直接返回日期:

    return leave_remaining
    

    【讨论】:

    • 我想返回天数。返回日期工作正常。感谢您的解决方案
    【解决方案3】:

    我认为最明显的答案是像这样定义您的 leave_remaining_days 道具:

    @property
    def leave_remaining_days(self):
        if self.is_accepted:
            return self.leave_days - 1
    

    不是吗?

    【讨论】:

    • 按照这个逻辑,它只会将天数减少一次1。但我想每天减少1
    • 对于您描述的任务,django 不提供内置功能,您应该使用 cron 作业或 celery 定期运行任务(在您的情况下每天一次)。
    【解决方案4】:

    你是这个意思吗?

    @property
    def leave_remaining_days(self):
        if self.is_accepted and not datetime.date.today() > self.end_day:
            leave_remaining = self.end_day - datetime.date.today()
            return leave_remaining.days
    

    【讨论】:

      【解决方案5】:

      这应该有效:

      def leave_remaining_days(self):
                  if self.is_accepted and not datetime.date.today() > self.end_day:
                      leave_remaining = self.end_day - datetime.timedelta(days=1)
                      return leave_remaining.day
      

      leave_remaining.day 将为您提供剩余的休假天数

      【讨论】:

        猜你喜欢
        • 2022-11-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2016-09-29
        • 2014-01-16
        • 2019-03-18
        • 1970-01-01
        • 2020-07-07
        相关资源
        最近更新 更多