スポンサードリンク



こんにちは。sinyです。

この記事ではDjangoのモデル実装を効率化する方法を簡単にまとめました。

抽象基底クラスを使って共通フィールドを定義

例えば、複数のアプリケーション、複数のモデル定義内において作成日時(created)更新日時(modified)のフィールドを共通で持たせたいといった場合に、各テーブルクラス内にcreatedとmodifiedを定義してもよいですが、テーブル数が多いとかなり冗長で長いコードになってしまいます。

そこで、共通するフィールドの定義を抽象基底クラスとして定義し、抽象基底クラスを承継することでモデル定義を簡素化することができます。

抽象基底クラスを定義する

まず、事前準備としてDjangoプロジェクトとアプリケーションを作成しておきます。

 

また、settings.pyに作成したアプリケーションを追加しておきます。

言語とタイムゾーンも変更してきます。

 

 

フォルダ構成は以下の通り

 

抽象基底クラス定義するmodels.pyを格納するためのフォルダ(core)を作成し、その配下にmodels.pyを作成しておきます。

 

core/models.pyに以下のコードを定義します。

 

抽象基底クラスとなる TimeStampedModelクラス(名称は任意)は通常通りmodels.Modelを承継して定義します。

 

TimeStampedModelクラスで他のクラスで共通的に利用したいフィールドを定義します。

今回はcreated(作成時刻)modified(更新時刻)のフィールドを定義しています。

このままだと普通のモデルクラスですが、最後の2行でこのクラスを抽象基底クラス化しています。

 

abstract = Trueとすることで抽象基底クラスになります。

続いて、アプリケーション(app)直下のmodels.pyに抽象基底クラスを承継したモデルクラステーブルを定義します。

app/models.py

 

以下のコードで先ほど作成したcore/models.pyのTimeStampedModelクラスをインポートしています。

 

TimeStampedModelクラスを承継してFlavorクラスを定義し、titleフィールドだけ定義します。

createdmodifiedフィールドは抽象基底クラスを承継しているのでFlavorクラス内で定義する必要がありません。

以上の設定でマイグレーションを実行すると、以下のようなSQL(sqliteのケース)でapp_flavorテーブルが実装されます。

 

 なお、抽象基底クラス(TimeStampedModel)を承継したクラスをマイグレーションしてもTimeStampedModelクラスのモデルテーブルは作成されません。

 

 Django 抽象基底クラスと Python スタンダード ライブラリの abc モジュールの抽象基底クラスは別物なので混同しないように注意

マイグレーション

それでは実際にマイグレーションしてみましょう。

 

 

SQLITEデータベースにアクセスして登録されたテーブルを確認してみます。

 

上記の通りapp_flavorテーブルが登録されていることが確認でいます。

実装時のSQL文も確認してみます。

 

上記の通り、titileだけでなくcreatedとmodifiedフィールドも実装されていることが確認できます。

ついでにadminサイト上の動作を確認してましょう。

app/admin.pyを以下の通り設定しておきます。

 

管理者ユーザも作成しておきましょう。

 

runserverを実行してadminサイト(http://127.0.0.1:8000/admin)にアクセスします。

 

Flavorテーブルにレコードを新規作成しようとすると、以下の通りFlavorクラスで定義したtitileフィールドだけ表示されています。

 

保存ボタンを押すとレコードが登録されます。

すると以下の通り承継先の抽象基底クラス(TimeStampedModel)で定義されているフィールドも自動的に生成されます。

ちなみに抽象基本クラスでないクラスを承継した場合は、承継先のモデルクラスのテーブルもデータベース上に登録されます。

 

以上、「Djangoのモデル実装を効率化する方法」でした。

おすすめの記事