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
First, open the views.py file of your Django application and import the datetime module. Next, use the datetime. now() method to get the current date and time value. Now, we can either assign this method to a variable or we can directly use this method wherever we required the datetime value.
What is @property in Django? Here is how I understand it: @property is a decorator for methods in a class that gets the value in the method. But, as I understand it, I can just call the method like normal and it will get it.
The auto_now_add will set the timezone. now() only when the instance is created, and auto_now will update the field everytime the save method is called. It is important to note that both arguments will trigger the field update event with timezone.
There is no need to implement custom save method.
Also doing this default=datetime.now()+timedelta(days=30)
is absolutely wrong! It gets evaluated when you start your instance of django. If you use apache it will probably work, because on some configurations apache revokes your django application on every request, but still you can find you self some day looking through out your code and trying to figure out why this get calculated not as you expect.
The right way of doing this is to pass a callable object to default argument. It can be a datetime.today function or your custom function. Then it gets evaluated every time you request a new default value.
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)
// 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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With