Django の ORM 抽象クラス の実装
DjangoのORM(Object Relational Mapper)は、データベースとのやり取りをPythonコードで行うことができる便利な機能です。そして、このORMには抽象クラスという機能があります。
抽象クラスとは、そのクラスを継承することで子クラスが必ず実装しなければならないメソッドを定義できるクラスです。DjangoのORMにおいては、抽象クラスを使うことで、共通のフィールドやメソッドを持ったモデルクラスを作成することができます。
例えば、以下のような抽象クラスを定義することができます。
from django.db import models
class BaseModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
この抽象クラスを継承することで、必ずcreated_atとupdated_atというフィールドを持つモデルクラスが作成できます。また、この抽象クラスにはMetaクラスのabstract=Trueというプロパティが設定されています。これにより、この抽象クラスを直接インスタンス化することができなくなります。
Django 3.1まではインスタンス化できましたがDjango3.2でインスタンス化すると以下の例外を発生するようになりました。
TypeError: Abstract models cannot be instantiated.
Pythonの抽象クラスの実装
一方で、Pythonで抽象クラスを実装するには、abc
モジュールを使います。抽象クラスを定義するには、abc.ABC
クラスを継承する必要があります。また、抽象メソッドを定義するには、@abstractmethod
デコレータをメソッドに付ける必要があります。以下は、抽象クラスの例です。
from abc import ABC, abstractmethod
class MyAbstractClass(ABC):
@abstractmethod
def my_abstract_method(self):
pass
class MyClass(MyAbstractClass):
def my_abstract_method(self):
print("MyClass's implementation of my_abstract_method.")
この例では、MyAbstractClass
は抽象クラスであり、my_abstract_method
は抽象メソッドです。MyClass
はMyAbstractClass
を継承していますが、my_abstract_method
を実装しています。MyClass
はMyAbstractClass
の実体化されたインスタンスですが、抽象クラスで定義された抽象メソッドを実装しているため、正常に動作します。