Best way to add common date_added, date_modified to many models in Django
-
21-09-2019 - |
Question
I am adding date_added and date_modified fields to a bunch of common models in my current project. I am subclassing models.Model and adding the appropriate fields, but I want to add automated save behavior (i.e: evey time anyone calls MyModel.save(), the date_modified field gets updated. I see two approaches: overriding the save() method or adding a pre_save signal handler in the abstract base class.
class CommonData(models.Model):
date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False)
date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True)
# register a handler for the pre_save to update date_modified
def pre_save_handler(sender, **kwargs):
date_modified = datetime.datetime.today
def __init__():
pre_save.connect(pre_save_handler, sender=self)
or
class CommonData(models.Model):
date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False)
date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True)
# overriding save
def save(force_insert=False,force_update=False):
date_modified = datetime.datetime.now
return models.Model.save(force_insert, force_update)
I'm new to Django and Python and wondered which approach was more "django"? Which is more efficient? which is the "right" way to do this?
Solution
Since you're new to Django, you might find the Django Command Extensions useful:
http://code.google.com/p/django-command-extensions/
... which conveniently includes a TimeStampedModel you can derive your models from:
http://code.google.com/p/django-command-extensions/wiki/ModelExtensions
An abstract base class model that provides self-managed "created" and "modified" fields.
OTHER TIPS
Did you try looking at DateTimeField
's auto_now=True
and auto_now_add=True
? They do just what you need automatically. Otherwise, there is no real difference between doing save override and signal handling - in fact, pre_save signal is being called from django model's save method.
Docs: http://docs.djangoproject.com/en/dev/ref/models/fields/#datefield
You can define these in an Abstract Base Class and then inherit from that. It's sort of like having a MixIn that also defines model fields.
Note that auto_now_add
and auto_now
uses pre_save
, which not working when bulk_create
or update
. Thus in your MySQL, for example, date_added field will be '0000-00-00 00:00:00' and it is possible to get warning: 'Warning: Column 'date_added' cannot be null'. So you can use auto_now* but you should be careful.