Let'sh
Abstract Model

Abstract Model

Introduction

While I was creating letsh application, I thought that there must be some data that could be shared throughout data no matter what they are. The best example for this could be time that data was newly created or updated. If I include these data, then admin users later will be able to easily control over those data based on those time data.

However, including all these common data into all other apps' models is just repeating codes ourselves and it could waste our DB. So it would be very effective to make these types of models that do not wasting too much DB space and can be used in other models.

Django is also suggesting DRY(Do NOT Repeat Yourself) (opens in a new tab), so let's keep our code more sexier!

This is where abstract model (opens in a new tab) is used. After I defined the common data fields, with class inheritance (opens in a new tab) other apps' models can also use Common model's data fields.


Initialization

To get start with creating an abstract model, I created common/ app in my project root route.


django-admin startapp common

Then included my app in INSTALLED_APPS (opens in a new tab) 내부에 설치해준다.

config/settings.py
Copy

INSTALLED_APPS = [
# ...
"common.apps.CommonConfig",
]


CommonDateModel

CommonDateModel is an abstract model for representing date. This model will be occasionally used where date data is needed.

  1. Date that user left comment
  2. Date that user created its own wishlist
  3. Date that user created reservation (check-in & check-out)

Creating Model Class

I created CommonDateModel model class.


from django.db import models
class CommonDateModel(models.Model):
"""Common Date Model Definition"""
pass

Meta Class Configuration

Meta class (opens in a new tab) allows us to do extra configuration on the model. As models in common/ app are abstract models, I set abstract = True as shown in documentaiton (opens in a new tab).

By doing this, it won't create tables in DB separately but still be able to use those abstract model fields in other models as well.


from django.db import models
class CommonDateModel(models.Model):
"""Common Date Model Definition"""
pass
class Meta:
abstract = True

DateField

Lastly I set fields.

DateField (opens in a new tab) is a field that literally controls with date. I set date created as created_date, and date updated as updated_date, respectively.

Here, auto_now_add (opens in a new tab) attribute is used when an object is automatically created as current date.

On the other hand, auto_now (opens in a new tab) attribute is used when object is updated and set update date as current date automatically.


from django.db import models
class CommonDateModel(models.Model):
"""Common Date Model Definition"""
created_date = models.DateField(auto_now_add=True, verbose_name=_("Created Date"))
updated_date = models.DateField(auto_now=True, verbose_name=_("Updated Date"))
class Meta:
abstract = True

Creating Model Class

I created CommonDateModel model class.

Meta Class Configuration

Meta class (opens in a new tab) allows us to do extra configuration on the model. As models in common/ app are abstract models, I set abstract = True as shown in documentaiton (opens in a new tab).

By doing this, it won't create tables in DB separately but still be able to use those abstract model fields in other models as well.

DateField

Lastly I set fields.

DateField (opens in a new tab) is a field that literally controls with date. I set date created as created_date, and date updated as updated_date, respectively.

Here, auto_now_add (opens in a new tab) attribute is used when an object is automatically created as current date.

On the other hand, auto_now (opens in a new tab) attribute is used when object is updated and set update date as current date automatically.


from django.db import models
class CommonDateModel(models.Model):
"""Common Date Model Definition"""
pass


CommonDateTimeModel

I followed exact same logic as I did above for CommonDateModel. The only difference is that since this model will control over both date and time, I used DateTimeField (opens in a new tab). This abstract model will be used in which models that require more precise date and time.

  1. Date and time when user created reservation
  2. Date and time when user created payment
  3. Date and time when user created abuse report
common/models.py
Copy

class CommonDateTimeModel(models.Model):
"""Common Date Time Model Definition"""
created_at = models.DateTimeField(
auto_now_add=True, verbose_name=_("Created Date & Time")
)
updated_at = models.DateTimeField(
auto_now=True, verbose_name=_("Updated Date & Time")
)
class Meta:
abstract = True

Result

If we add field defined in abstract base model in other apps' admin.py, we can see it is nicely put into admin panel as below.


result

But then if we take a look at common/ app's database, we can find out that there has been no migration happened for TimeStampModel (See blue bracket). By doing this, we can effectively manage database.


result2