Django modeli form nesneleri için otomatik oluşturma tarihi?


164

Bir nesne için otomatik olarak oluşturma tarihi ve ayrıca nesnenin en son ne zaman güncellendiğini kaydedecek bir alan belirlemenin en iyi yolu nedir?

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')

Şu hatayı alıyorum:

objects_object.created_at may not be NULL

Bu değeri kendim manuel olarak ayarlamam gerekir mi? Bunun aktarılan parametrelerin amacı olduğunu düşündüm DateTimeField(veya bunlar sadece varsayılanlar mı editable=Falseve formda görüntülenmeyeceklerini belirlediğim için, talepte gönderilmiyorlar ve bu nedenle forma koymak?).

Bunu yapmanın en iyi yolu nedir? Bir __init__yöntem mi?

Yanıtlar:


326

Sırasıyla ve için auto_nowve auto_now_addseçeneklerini kullanabilirsiniz .updated_atcreated_at

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

33
auto_nowve auto_now_addkötü olarak kabul edilirler, bu yüzden onlardan uzak durmaya çalışın. Bu cevap , nedenini açıklar ve save()yöntemi geçersiz kılarak daha iyi bir yaklaşım sağlar .
gregoltsov

3
bu hatayı üretir: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



2
Sanırım @ gregoltsov'un yorumu bu noktada güncel değil. Kullanmak auto_now_addveya auto_nowgayet iyi çalışıyor. Modeli kaydetmeden önce alanı ayarlar ( github.com/django/django/blob/stable/3.0.x/django/db/models/… ).
yndolok

39

Eh, yukarıdaki cevap doğrudur, auto_now_add ve auto_now bunu yapar, ancak soyut bir sınıf yapmak ve onu ihtiyaç duyduğunuz herhangi bir modelde created_atve updated_atalanlarda kullanmak daha iyi olacaktır .

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

    class Meta:
        abstract = True

Artık onu kullanmak istediğiniz her yerde basit bir devralma yapabilir ve istediğiniz modelde zaman damgasını kullanabilirsiniz.

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

Bu şekilde, Django DRY'de nesne yönelimli yeniden kullanılabilirlikten yararlanabilirsiniz (kendinizi tekrar etmeyin)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.