views:

68

answers:

3

Hay guys, as the title suggests. I want to add 30 days to the DateField field. This is auto populated on creation of record using auto_now_add=True

Any ideas how to go about doing this?

Thanks

+1  A: 

Use Pythons 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()

And from the Django documentation:

DateField
A date, represented in Python by a datetime.date instance.

If you want to add 30 days on creation of the object, forget about auto_now_add=True and do as becomingGuru suggests. Information about overriding save() can also be found in the Django documentation.

Felix Kling
+1  A: 

Override the save on the model and while saving, check if pk is populated.

>>> 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)
Lakshman Prasad
+2  A: 

// Update

The comment under the original post got me thinking. I guess this is the best solution so far:

from datetime import datetime, timedelta

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

// 2. Update

If you want to define a model attribute which holds the amount of days that should be added you are going to need to override the save method. So far I could'nt come up with a simpler way.

Solution:

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()

As becomingGuru already suggested you should override your models save method.

Example:

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()

This is not the best way for me since you have to save the model twice. But using auto_now_add requires you to save the model first before a datetime instance for mydate is created.

Another approach which would require only one save:

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()

Hope that helped!

Jens
Works perfectly thanks!
dotty
UPDATE: Worked as expected, however the 30 days is going to be a variable. It could be 30 days, 60 days, 90 days, etc. Any ideas? Should i add a 'expires_in' field which holds the amount of days it expires in? How could i use this new 'expires_in' field to edit the line "timedelta(days=30)" ?
dotty
Do I understand you correctly? You want another model field which holds a value describing how much days are going to be added?
Jens
Correct. Any ideas?
dotty
This seems to work: d = timedelta(days=self.expires_in)
dotty
Overriding the save method is the "django" way to do it.
Andrew Sledge
I might be wrong but I think your first solution (with `default=datetime.now()+timedelta(days=30)`) is wrong. The module is loaded once at server startup, so `datetime.now()` is only executed when the server starts (not when a new instance is added).
Felix Kling
Perfect answer thank you very much.
dotty