J'ai le modèle db ci-dessous:
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)
J'ajoute une nouvelle instance en utilisant ce qui suit:
tp = TermPayment.objects.create(**kwargs)
Mon problème: tous les enregistrements de la base de données ont la même valeur dans le champ date, qui est la date du premier paiement. Après le redémarrage du serveur, un enregistrement a la nouvelle date et les autres enregistrements ont le même que le premier. Il semble que certaines données soient mises en cache, mais je ne trouve pas où.
base de données: mysql 5.1.25
django v1.1.1
default=datetime.now
- Note, sans appeler comme dansnow()
pas la norme pour DateTimeField, mais ... anycase à portée de main.Réponses:
il semble qu'il
datetime.now()
soit en cours d'évaluation lorsque le modèle est défini, et non chaque fois que vous ajoutez un enregistrement.Django a une fonctionnalité pour accomplir ce que vous essayez déjà de faire:
ou
La différence entre le deuxième exemple et ce que vous avez actuellement est le manque de parenthèses. En passant
datetime.now
sans les parenthèses, vous passez la fonction réelle, qui sera appelée chaque fois qu'un enregistrement est ajouté. Si vous la transmettezdatetime.now()
, vous évaluez simplement la fonction et lui transmettez la valeur de retour.Plus d'informations sont disponibles sur la référence de champ de modèle de Django
la source
expiry = models.DateTimeField(default=datetime.now + timedelta(days=30))
def now_plus_30(): return datetime.now() + timedelta(days = 30)
, puis utilisermodels.DateTimeField(default=now_plus_30)
default=lambda: datetime.now()+timedelta(days=30)
Au lieu d'utiliser,
datetime.now
vous devriez vraiment utiliserfrom django.utils.timezone import now
Référence:
django.utils.timezone.now
alors optez pour quelque chose comme ça:
la source
auto_now_add
(qui est conscient du fuseau horaire), vous pouvez obtenir des calculs erronés en raison de différences de fuseau horaire erronées.Dans la documentation sur le champ par défaut du modèle django:
La valeur par défaut du champ. Cela peut être une valeur ou un objet appelable. S'il est appelable, il sera appelé chaque fois qu'un nouvel objet est créé.
Par conséquent, ce qui suit devrait fonctionner:
la source
default
( django-chinese-docs-14.readthedocs.io/en/latest/ref/models/… )David avait la bonne réponse. La parenthèse () fait en sorte que le timezone.now () appelable soit appelé chaque fois que le modèle est évalué. Si vous supprimez le () de timezone.now () (ou datetime.now (), si vous utilisez l'objet datetime naïf) pour le faire juste ceci:
Ensuite, cela fonctionnera comme vous vous y attendez: les
nouveaux objets recevront la date actuelle lors de leur création, mais la date ne sera pas remplacée à chaque fois que vous faites manage.py makemigrations / migrate.
Je viens de rencontrer cela. Merci beaucoup à David.
la source
Le
datetime.now()
est évalué lorsque la classe est créée, pas lorsqu'un nouvel enregistrement est ajouté à la base de données.Pour réaliser ce que vous voulez, définissez ce champ comme:
De cette façon, le
date
champ sera défini à la date actuelle pour chaque nouvel enregistrement.la source
La réponse à celle-ci est en fait fausse.
Remplissage automatique de la valeur (auto_now / auto_now_add n'est pas le même que par défaut). La valeur par défaut sera en fait ce que l'utilisateur voit s'il s'agit d'un tout nouvel objet. Ce que je fais généralement, c'est:
Assurez-vous, si vous essayez de représenter cela dans une page d'administration, que vous le répertoriez comme «read_only» et référencez le nom du champ
Encore une fois, je le fais car ma valeur par défaut n'est généralement pas modifiable et les pages d'administration ignorent les éléments non modifiables, sauf indication contraire. Il y a certainement une différence cependant entre la définition d'une valeur par défaut et l'implémentation de l'auto_add qui est la clé ici. Testez-le!
la source
datetime.now()
est évalué une fois, lorsque votre classe est instanciée. Essayez de supprimer les parenthèses pour que la fonctiondatetime.now
soit renvoyée et ALORS évaluée. J'ai eu le même problème avec la définition de valeurs par défaut pour mesDateTimeField
s et j'ai rédigé ma solution ici .la source
Dans la référence du langage Python, sous Définitions des fonctions :
Heureusement, Django a un moyen de faire ce que vous voulez, si vous utilisez l'
auto_now
argument pourDateTimeField
:Voir les documents Django pour DateTimeField .
la source
Dans Django 3.0
auto_now_add
semble fonctionner avecauto_now
reg_date=models.DateField(auto_now=True,blank=True)
la source