Automatisches Erstellungsdatum für Django-Modellformularobjekte?

152

Was ist der beste Weg, um ein Erstellungsdatum für ein Objekt automatisch festzulegen und auch ein Feld, das aufzeichnet, wann das Objekt zuletzt aktualisiert wurde?

models.py:

created_at = models.DateTimeField(False, True, editable=False)
updated_at = models.DateTimeField(True, True, editable=False)

views.py:

if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        return HttpResponseRedirect('obj_list')

Ich bekomme den Fehler:

objects_object.created_at may not be NULL

Muss ich diesen Wert manuell einstellen? Ich dachte, das war der Punkt, an den die Parameter übergeben wurden DateTimeField(oder sind sie nur Standardeinstellungen, und da ich sie festgelegt habe, werden editable=Falsesie nicht im Formular angezeigt, daher werden sie nicht in der Anfrage gesendet und daher auch nicht in die Form bringen?).

Was ist der beste Weg, dies zu tun? Eine __init__Methode?

Roger
quelle

Antworten:

310

Sie können die Verwendung auto_nowund auto_now_addOptionen für updated_atund created_atjeweils.

class MyModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
Manoj Govindan
quelle
31
auto_nowund auto_now_addgelten als böse, also versuche sie zu vermeiden. Diese Antwort erklärt, warum und bietet einen besseren Ansatz, der die save()Methode überschreibt .
Gregoltsov
3
es erzeugt diesen Fehler:You are trying to add a non-nullable field 'created_at' to gameuser without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows) 2) Quit, and let me add a default in models.py Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now() >>> timezone.now()
Kaleem Ullah
1
Löschen Sie die Zeilen in der Datenbank oder aktivieren Sie Option 1 und fügen Sie timezone.now ()
mullerivan hinzu.
Wählen Sie eine Option aus: 1 Geben Sie jetzt den Standardwert als gültigen Python ein. Die Module datetime und django.utils.timezone sind verfügbar, sodass Sie z. B. timezone.now () >>> timezone.now () Migrationen für 'aml_validations' durchführen können. :
Mullerivan
26

Nun, die obige Antwort ist richtig, auto_now_add und auto_now würden es tun, aber es wäre besser, eine abstrakte Klasse zu erstellen und sie in jedem Modell zu verwenden, in dem Sie created_atund updated_atFelder benötigen .

class TimeStampMixin(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

Jetzt können Sie überall dort, wo Sie es verwenden möchten, eine einfache Vererbung durchführen und den Zeitstempel in jedem Modell verwenden, das Sie mögen.

class Posts(TimeStampMixin):
    name = models.CharField(max_length=50)
    ...
    ...

Auf diese Weise können Sie die objektorientierte Wiederverwendbarkeit in Django DRY nutzen (wiederholen Sie sich nicht).

Chitrank Dixit
quelle