我的django模型DateField如何在提供的值上添加30天?

dot*_*tty 22 django model datefield

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

任何想法如何去做?

谢谢

Sim*_*nas 54

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

这样做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)
Run Code Online (Sandbox Code Playgroud)

  • 我用这个很多!当您想要获得不超过20天左右的所有帖子时特别有用.只需使用`BlogPost.objects.filter(pub_date__gt = datetime.now() - timedelta(days = 20)'.这转换为SQL,因此非常有效![参考django docs](https://docs.djangoproject. COM/EN /开发/ REF /模型/查询集/#现场查询) (3认同)

Jen*_*ens 38

//更新

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

from datetime import datetime, timedelta

class MyModel(models.Model):
   mydate = models.DateTimeField(default=datetime.now()+timedelta(days=30))
Run Code Online (Sandbox Code Playgroud)

// 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()
Run Code Online (Sandbox Code Playgroud)

正如BecomeGuru已经建议你应该覆盖你的模型保存方法.

例:

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()
Run Code Online (Sandbox Code Playgroud)

这对我来说不是最好的方法,因为你必须保存模型两次.但是使用auto_now_add要求您在创建mydate的datetime实例之前先保存模型.

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

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()
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!

  • 我可能错了,但我认为你的第一个解决方案(使用`default = datetime.now()+ timedelta(days = 30)`)是错误的.模块在服务器启动时加载一次,因此`datetime.now()`仅在服务器启动时执行(而不是在添加新实例时执行). (10认同)

Fel*_*ing 5

使用 Python 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()
Run Code Online (Sandbox Code Playgroud)

Django 文档中

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

如果你想在创建对象时增加 30 天,忘记auto_now_add=True并按照成为大师的建议去做。有关覆盖的信息save()也可以在Django 文档中找到。