What's the best way to set a creation date for an object automatically, and also a field that will record when the object was last updated?
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')
I get the error:
objects_object.created_at may not be NULL
Do I have to manually set this value myself? I thought that was the point of the parameters passed to DateTimeField
(or are they just defaults, and since I've set editable=False
they don't get displayed on the form, hence don't get submitted in the request, and therefore don't get put into the form?).
What's the best way of doing this? An __init__
method?
You can use the auto_now
and auto_now_add
options for updated_at
and created_at
respectively.
class MyModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Well, the above answer is correct, auto_now_add and auto_now would do it, but it would be better to make an abstract class and use it in any model where you require created_at
and updated_at
fields.
class TimeStampMixin(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
Now anywhere you want to use it you can do a simple inherit and you can use timestamp in any model you make like.
class Posts(TimeStampMixin):
name = models.CharField(max_length=50)
...
...
In this way, you can leverage object-oriented reusability, in Django DRY(don't repeat yourself)
composition over inheritance
. Taking inspiration from libs/frameworks is okay, but remember that project code doesn't need to be as reusable. It needs to be quickly modifiable though and adding layers of inheritance can hurt in that regard.
It is impossible to add the field 'create_at' with 'auto_now_add=True' to local without providing a default. This is because the database needs something to popula te existing rows
Success story sharing
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()
auto_now_add
orauto_now
works just fine. It sets the field before saving the model (github.com/django/django/blob/stable/3.0.x/django/db/models/…).