Web Development with Django Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

Creating a model mixin to handle creation and modification dates

It is a common behavior to have timestamps in your models for the creation and modification of your model instances. In this recipe, we will see how to create a simple model mixin that saves the creation and modification dates and times for your model. Using such a mixin will ensure that all the models use the same field names for the timestamps and have the same behavior.

Getting ready

If you haven't done this yet, create the utils package to save your mixins. Then, create the models.py file in the utils package.

How to do it…

Open the models.py file of your utils package and insert the following content there:

# utils/models.py
# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import now as timezone_now

class CreationModificationDateMixin(models.Model):
  """
  Abstract base class with a creation and modification
  date and time
  """

  created = models.DateTimeField(
    _("creation date and time"),
    editable=False,
  )

  modified = models.DateTimeField(
    _("modification date and time"),
    null=True,
    editable=False,
  )

  def save(self, *args, **kwargs):
    if not self.pk:
      self.created = timezone_now()
    else:
      # To ensure that we have a creation data always,
      # we add this one
    if not self.created:
      self.created = timezone_now()

      self.modified = timezone_now()

      super(CreationModificationDateMixin, self).\
      save(*args, **kwargs)
    save.alters_data = True

  class Meta:
    abstract = True

How it works…

The CreationModificationDateMixin class is an abstract model, which means that extending model classes will create all the fields in the same database table, that is, there will be no one-to-one relationships that make the table difficult to handle. This mixin has two date-time fields and the save() method that will be called when saving the extended model. The save() method checks whether the model has no primary key, which is the case of a new not-yet-saved instance. In this case, it sets the creation date to the current date and time. If the primary key exists, the modification date is set to the current date and time.

Alternatively, instead of the save() method, you can use the auto_now_add and auto_now attributes for the created and modified fields, which will add creation and modification timestamps automatically.

See also

  • The Using model mixins recipe
  • The Creating a model mixin to take care of meta tags recipe
  • The Creating a model mixin to handle generic relations recipe