Tengo el siguiente modelo de base de datos:
from datetime import datetime
class TermPayment(models.Model):
# I have excluded fields that are irrelevant to the question
date = models.DateTimeField(default=datetime.now(), blank=True)
Agrego una nueva instancia usando lo siguiente:
tp = TermPayment.objects.create(**kwargs)
Mi problema: todos los registros en la base de datos tienen el mismo valor en el campo de fecha, que es la fecha del primer pago. Después de que el servidor se reinicia, un registro tiene la nueva fecha y los otros registros tienen el mismo que el primero. Parece que algunos datos están almacenados en caché, pero no puedo encontrar dónde.
base de datos: mysql 5.1.25
django v1.1.1
default=datetime.now
- nota, sin llamar como ennow()
No es el estándar para DateTimeField, pero ... práctico en cualquier caso.Respuestas:
parece que
datetime.now()
se está evaluando cuando se define el modelo, y no cada vez que agrega un registro.Django tiene una función para lograr lo que está intentando hacer:
o
La diferencia entre el segundo ejemplo y lo que tiene actualmente es la falta de paréntesis. Al pasar
datetime.now
sin paréntesis, pasa la función real, que se llamará cada vez que se agregue un registro. Si lo pasadatetime.now()
, solo está evaluando la función y pasándole el valor de retorno.Más información está disponible en la referencia de campo modelo de Django
fuente
expiry = models.DateTimeField(default=datetime.now + timedelta(days=30))
def now_plus_30(): return datetime.now() + timedelta(days = 30)
, y luego usarmodels.DateTimeField(default=now_plus_30)
default=lambda: datetime.now()+timedelta(days=30)
En lugar de usar
datetime.now
, realmente deberías estar usandofrom django.utils.timezone import now
Referencia:
django.utils.timezone.now
así que ve por algo como esto:
fuente
auto_now_add
(que tiene en cuenta la zona horaria), puede obtener cálculos incorrectos debido a las diferencias de zona horaria erróneas.De la documentación en el campo predeterminado del modelo django:
El valor predeterminado para el campo. Esto puede ser un valor o un objeto invocable. Si se puede llamar, se llamará cada vez que se cree un nuevo objeto.
Por lo tanto, lo siguiente debería funcionar:
fuente
default
( django-chinese-docs-14.readthedocs.io/en/latest/ref/models/… )David tenía la respuesta correcta. El paréntesis () hace que se llame al timezone.now () invocable cada vez que se evalúa el modelo. Si elimina el () de timezone.now () (o datetime.now (), si usa el ingenuo objeto datetime) para que sea así:
Entonces funcionará como espera: los
nuevos objetos recibirán la fecha actual cuando se creen, pero la fecha no se anulará cada vez que administre.py makemigrations / migrate.
Acabo de encontrar esto. Muchas gracias a David.
fuente
El
datetime.now()
se evalúa cuando se crea la clase, no cuando se agrega un nuevo registro a la base de datos.Para lograr lo que desea, defina este campo como:
De esta manera, el
date
campo se establecerá en la fecha actual para cada nuevo registro.fuente
La respuesta a esta pregunta es realmente incorrecta.
Rellenar automáticamente el valor (auto_now / auto_now_add no es lo mismo que el predeterminado). El valor predeterminado será en realidad lo que el usuario ve si es un objeto nuevo. Lo que normalmente hago es:
Asegúrese de que, si está tratando de representar esto en una página de administración, lo enumere como 'solo lectura' y haga referencia al nombre del campo
Nuevamente, hago esto ya que mi valor predeterminado no suele ser editable, y las páginas de administración ignoran los no editables a menos que se especifique lo contrario. Sin embargo, hay una diferencia entre establecer un valor predeterminado e implementar auto_add, que es clave aquí. ¡Pruébalo!
fuente
datetime.now()
se evalúa una vez, cuando se instancia su clase. Intente eliminar el paréntesis para que la funcióndatetime.now
se devuelva y luego se evalúe. Tuve el mismo problema con el establecimiento de valores predeterminados para misDateTimeField
correos electrónicos y escribí mi solución aquí .fuente
De la referencia del lenguaje Python, en Definiciones de funciones :
Afortunadamente, Django tiene una manera de hacer lo que quiere, si usa el
auto_now
argumento paraDateTimeField
:Vea los documentos de Django para DateTimeField .
fuente
En Django 3.0
auto_now_add
parece funcionar conauto_now
reg_date=models.DateField(auto_now=True,blank=True)
fuente