5π
β
Your base model must be abstract:
class LogModel(models.Model):
class Meta:
abstract = True
created = models.DateTimeField(editable=False)
updated = models.DateTimeField()
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
# Use self._state.adding to check if this is a new instance,
# ID not being empty is not a guarantee that the instance
# exists in the database
# and if `update_fields` is passed, you must add the fields to the
# list or they won't be saved in the database.
if force_insert or self._state.adding:
self.created = timezone.now()
if update_fields and 'created' not in update_fields:
update_fields.append('created')
self.updated = timezone.now()
if update_fields and 'updated' not in update_fields:
update_fields.append('updated')
return super(LogModel, self).save(*args, **kwargs)
However, if you override the save()
method, this means it wonβt be editable in any form. If this is what you want, then you are better to use auto_now
and auto_now_add
:
class LogModel(models.Model):
class Meta:
abstract = True
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
π€Antoine Pinsard
1π
Instead of overriding save method, you could define auto_now_add and auto_now parameters in the Model field like:
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
For more information on these parameters, you can check the django docs.
- [Django]-How can I include related fields to the model serialization in django rest framework?
- [Django]-DJANGO β Change text color based on value (HTML & JS)
1π
It can be done by defining Abstract Base Model and define save method there and create all the models by inheriting from the abstract class. e.g.
class MyAbstractModel(models.Model):
created = models.DateTimeField(editable=False)
updated = models.DateTimeField()
def save(self, *args, **kwargs):
if self._state.adding:
self.created = timezone.now()
self.updated = timezone.now()
return super(LogModel, self).save(*args, **kwargs)
class Meta:
abstract = True
and create child model class from it:
class Record(MyAbstractModel):
pass
0π
Unfortunately, using update_fields
in .save()
does not trigger fields with auto_now
, so I overridden save
method this way:
class BaseModel(models.Model):
class Meta:
abstract = True
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
_base_update_fields = ['updated_at']
def save(
self, force_insert=False, force_update=False,
using=None, update_fields=None
):
_update_fields = None
if update_fields is not None:
_update_fields = self._base_update_fields + update_fields
super().save(
force_insert=force_insert, force_update=force_update,
using=using, update_fields=_update_fields
)
π€Ersain
Source:stackexchange.com