Standardoptionen für Django DateField

80

Ich habe ein Modell mit einem Datums- / Uhrzeitfeld:

date = models.DateField(_("Date"), default=datetime.now())

Wenn ich die App im eingebauten Django-Administrator überprüfe, wird DateFieldauch die Zeit daran angehängt, sodass beim Versuch, sie zu speichern, ein Fehler zurückgegeben wird. Wie mache ich die Standardeinstellung nur das Datum? ( datetime.today()funktioniert auch nicht)

Damon
quelle

Antworten:

149

Aus diesem Grund sollten Sie immer das Basismodul importieren datetime:import datetime und nicht die datetimeKlasse in diesem Modul : from datetime import datetime.

Der andere Fehler, den Sie gemacht haben, besteht darin, die Funktion standardmäßig mit dem aufzurufen (). Dies bedeutet, dass alle Modelle das Datum zum Zeitpunkt der ersten Definition der Klasse erhalten. Wenn Ihr Server also Tage oder Wochen ohne Neustart von Apache aktiv bleibt, erhalten alle Elemente das gleiche Datum.

Das Feld sollte also sein:

import datetime
date = models.DateField(_("Date"), default=datetime.date.today)
Daniel Roseman
quelle
Gibt es eine Möglichkeit, ein Zeitdelta hinzuzufügen? Zum Beispiel: default = datetime.date.today + datetime.timedelta (Tage = 4) ... dieser Code funktioniert nicht, aber das ist die Idee. (Zugegeben, die Speichermethode ist ein Ort, um dies zu tun, aber ich frage mich nur, ob es einen Weg gibt, dies als Teil der Definition zu tun.)
Joe J
1
@ Joe J: Das sollte wirklich eine neue Frage sein. Die Tatsache, dass Sie eine aufrufbare Funktion verwenden können, bedeutet jedoch, dass Sie einfach Ihre eigene Funktion definieren können, die heute + 4 zurückgibt.
Daniel Roseman
21
Was _("Date")macht das
Benregn
10
@benregn Es gibt dem Feld die Bezeichnung "Datum", markiert es jedoch für die Übersetzung mithilfe des Internationalisierungssystems.
Daniel Roseman
Vielen Dank, dass Sie das klargestellt haben. Ich habe gerade mit Django dev begonnen und es war mir ein bisschen unklar, ob es mehr als nur das Beschriften bedeutet.
Benregn
38

Ihr Fehler ist die Verwendung des datetimeModuls anstelle des dateModuls. Du wolltest das machen:

from datetime import date
date = models.DateField(_("Date"), default=date.today)

Wenn Sie nur das aktuelle Datum erfassen möchten, verwenden Sie den folgenden auto_now_addParameter.

date = models.DateField(_("Date"), auto_now_add=True)

Doch die modelfield docs eindeutig fest , dass auto_now_addund auto_nowwird immer das aktuelle Datum verwendet und ist kein Standardwert , dass Sie außer Kraft setzen können.

Eric Palakovich Carr
quelle
8
date = models.DateTimeField(default=datetime.now, blank=True)
andyshi
quelle
5
DateTimeField ist nicht dasselbe. Wenn Sie für ein DateField standardmäßig eine Datums- / Uhrzeitangabe angeben, treten Probleme auf.
Onekiloparsec
5

Ich denke, ein besserer Weg, dies zu lösen, wäre die Verwendung von datetime callable:

from datetime import datetime

date = models.DateField(default=datetime.now)

Beachten Sie, dass keine Klammern verwendet wurden. Wenn Sie Klammern verwenden, rufen Sie die now()Funktion nur einmal auf (wenn das Modell erstellt wird). Stattdessen übergeben Sie den Callable als Argument und werden so jedes Mal aufgerufen, wenn eine Instanz des Modells erstellt wird.

Dank an Django Musings . Ich habe es benutzt und funktioniert gut.

ppicom
quelle
4

Dies sollte den Trick tun:

models.DateTimeField(_("Date"), auto_now_add = True)
btk
quelle
1
Mein Freund, ich glaube du hast es falsch gelesen. Die Frage bezieht sich auf DateField und nicht auf DateTimeField.
xxbinxx
2

Sie könnten auch verwenden lambda. Nützlich, wenn Sie django.utils.timezone.now verwenden

date = models.DateField(_("Date"), default=lambda: now().date())
Neil
quelle
6
Schauen Sie sich die Dokumentation an . Es ist nicht gut, Lambda als standardmäßige aufrufbare Hülle zu verwenden: Note that lambdas cannot be used for field options like default because they cannot be serialized by migrations. See that documentation for other caveats.
Pulina
@pulina Sie haben Recht, aber in diesem Fall, wenn Sie Datum an konfigurierte Zeitzone gebunden benötigen, sieht dies wie die einzige Lösung aus
oxfn
Nee. Sie können eine tatsächliche Funktion im Code anzeigen. Jede Funktion oder Methodenreferenz gemäß dieser in Verbindung, die eine Modellfunktion der obersten Ebene ist.
Pulina