34

正如标题所示。我想在该DateField领域增加 30 天。这是在使用创建记录时自动填充的auto_now_add=True

任何想法如何去做这件事?

谢谢

4

5 回答 5

67

无需实现自定义保存方法。

这样做default=datetime.now()+timedelta(days=30)也是绝对错误的!当您启动 django 实例时,它会被评估。如果您使用 apache,它可能会起作用,因为在某些配置中,apache 会在每个请求上撤销您的 django 应用程序,但您仍然可以在某天查看您的代码并试图找出为什么计算结果不符合您的预期。

这样做的正确方法是将可调用对象传递给默认参数。它可以是 datetime.today 函数或您的自定义函数。然后,每次您请求新的默认值时都会对其进行评估。

def get_deadline():
    return datetime.today() + timedelta(days=20)

class Bill(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(User, related_name='bills')
    date = models.DateField(default=datetime.today)
    deadline = models.DateField(default=get_deadline)
于 2013-03-08T08:15:10.150 回答
59

// 更新

原帖下的评论让我思考。我想这是迄今为止最好的解决方案:

from datetime import datetime, timedelta

class MyModel(models.Model):
   mydate = models.DateTimeField(default=datetime.now()+timedelta(days=30))

// 2. 更新

如果你想定义一个模型属性来保存应该添加的天数,你将需要覆盖 save 方法。到目前为止,我想不出更简单的方法。

解决方案:

class MyModel(models.Model):
  mydate = models.DateTimeField(editable=False)
  daysadded = models.IntegerField()

  def save(self):
    from datetime import datetime, timedelta
    d = timedelta(days=self.daysadded)

    if not self.id:
      self.mydate = datetime.now() + d
      super(MyModel, self).save()

正如becomingGuru 已经建议的那样,您应该覆盖您的模型保存方法。

例子:

class MyModel(models.Model):
  mydate = models.DateTimeField(auto_now_add=True)      

  def save(self):
    from datetime import timedelta
    d = timedelta(days=30)

    // only add 30 days if it's the first time the model is saved
    if not self.id:
      // not saving the model before adding the timedelta gave me errors 
      super(MyModel, self).save()

      self.mydate += d

      // final save
      super(MyModel, self).save()

这对我来说不是最好的方法,因为您必须保存模型两次。但是使用 auto_now_add 需要您在创建 mydate 的日期时间实例之前先保存模型。

另一种只需要一次保存的方法:

class MyModel(models.Model):
  mydate = models.DateTimeField(editable=False) // editable=False to hide in admin

  def save(self):
    from datetime import datetime, timedelta
    d = timedelta(days=30)

    // only add 30 days if it's the first time the model is saved
    if not self.id:
      self.mydate = datetime.now() + d
      super(MyModel, self).save()

希望有帮助!

于 2010-02-04T11:52:49.187 回答
5

使用蟒蛇timedelta

from datetime import timedelta
d = timedelta(days=30)

# object is your current instance of the model
object.yourdatefield += d
# or this because I am not sure whether the previous works
object.yourdatefield = object.yourdatefield + d

object.save()

Django 文档中:

DateField
一个日期,在 Python 中由一个datetime.date实例表示。

如果您想在创建对象时添加 30 天,请忘记auto_now_add=True并按照 becomeGuru 的建议进行操作。有关覆盖的信息save()也可以在Django 文档中找到。

于 2010-02-04T11:00:31.337 回答
1

覆盖模型上的保存,并在保存时检查 pk 是否已填充。

>>> from datetime import datetime
>>> from datetime import timedelta
>>> cur_date = datetime.now()
>>> cur_date
datetime.datetime(2010, 2, 4, 5, 0, 24, 437405)
>>> cur_date+timedelta(days=30)
datetime.datetime(2010, 3, 6, 5, 0, 24, 437405)
于 2010-02-04T11:01:52.467 回答
0

timedelta 的文档: https ://docs.python.org/2/library/datetime.html

def make_timedelta(seconds):
        return timedelta(days=seconds // 86399, seconds=seconds % 86399)
于 2017-02-09T15:53:00.267 回答