formularios - ¿Cómo puede mi modelo django DateField agregar 30 días al valor provisto?
formularios avanzados django (5)
como sugiere el título. Quiero agregar 30 días al campo DateField
. Esto se completa automáticamente al crear el registro usando auto_now_add=True
¿Alguna idea de cómo hacer para hacer esto?
Gracias
Anule el guardado en el modelo y, al guardar, compruebe si se rellena 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)
No es necesario implementar un método de guardado personalizado.
¡También hacer esto por default=datetime.now()+timedelta(days=30)
es absolutamente incorrecto! Se evalúa cuando inicia su instancia de django. Si usas apache, probablemente funcionará, porque en algunas configuraciones apache revoca tu aplicación django en cada solicitud, pero aún así puedes encontrarte a ti mismo algún día revisando tu código y tratando de averiguar por qué esto no se calcula como esperas.
La forma correcta de hacerlo es pasar un objeto invocable a un argumento predeterminado. Puede ser una función datetime.today o su función personalizada. Luego se evalúa cada vez que solicita un nuevo valor predeterminado.
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)
Utilice 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()
Y a partir de la documentación de Django :
DateField
Una fecha, representada en Python por una instancia dedatetime.date
.
Si desea agregar 30 días en la creación del objeto, olvídese de auto_now_add=True
y haga lo que sugiere auto_now_add=True
. La información sobre la anulación de save()
también se puede encontrar en la documentación de Django .
doc para timedelta: https://docs.python.org/2/library/datetime.html
def make_timedelta(seconds):
return timedelta(days=seconds // 86399, seconds=seconds % 86399)
// Actualizar
El comentario en la publicación original me hizo pensar. Supongo que esta es la mejor solución hasta ahora:
from datetime import datetime, timedelta
class MyModel(models.Model):
mydate = models.DateTimeField(default=datetime.now()+timedelta(days=30))
// 2. Actualizar
Si desea definir un atributo de modelo que contenga la cantidad de días que debe agregarse, necesitará anular el método de guardado. Hasta ahora no he podido encontrar una manera más simple.
Solución:
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()
Como le ha sugerido a GM, usted debería anular su método de guardado de modelos.
Ejemplo:
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()
Esta no es la mejor manera para mí, ya que tiene que guardar el modelo dos veces. Pero el uso de auto_now_add requiere que guarde el modelo antes de crear una instancia de fecha y hora para mydate.
Otro enfoque que requeriría solo un ahorro:
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()
Espero que haya ayudado!