[Django]models.pyを複数のファイルに分割する

DjangoWebアプリケーションの開発をしているとモデル部分を実装する「models.py」というファイルのコード量が多くなることがあります。テーブル数とフィールド数に依存してコード量が増えるので、アプリケーションの規模が大きくなるとファイルのコード量は自然と増えていきます。コード量が増えすぎると可読性が低下するという問題もあるので、今回はこの「models.py」というファイルの分割方法を説明していきたいと思います。

コーディング規約などで1ファイルあたりのコード量に規制がある場合にも活用できると思います。

前提条件

  • Python:3.9.1
  • Django:3.1.4

通常のmodels.py

通常「models.py」はこのように配置されています。

app/
  __init__.py
  models.py

models.pyには下記のclassが実装されているものとします。

from django.db import models


class Sample(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)


class Test(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)

この「models.py」を分割したいんですが、

app/
  __init__.py
  models_sample.py
  models_test.py

このように分割しても正しくモデルと認識されません。

models.pyを分割する

models.py」を分割するにはまず、「modelsディレクトリ」を作成する必要があり、作成したmodelsディレクトリに「__init__.py」と分割した「models.py」を作成します。

app/
  __init__.py
  models/
    __init__.py
    sample.py
    test.py

sample.py」と「test.py」は下記の通り。

sample.py

from django.db import models


class Sample(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)

test.py

from django.db import models


class Test(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)

ただ、これだけだと「manage.py」の「makemigraitonsコマンド」や「migrateコマンド」でモデルが認識されません。

そこで、「__init__.py」と「モデルのclass」に手を加えます。

__init__.py

from app.models.sample import Sample
from app.models.test import Test

モデルクラスの「Sampleクラス」と「Testクラス」をインポートします。

sample.py

from django.db import models


class Sample(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)

    class Meta:
        app_label = 'app'

test.py

from django.db import models


class Test(models.Model):
    value = models.CharField(max_length=20, default=0, blank=True)

    class Meta:
        app_label = 'app'

DjangoMetaオプションの「app_label」にアプリケーション名を設定します。アプリケーション名と「app_label」を一致させることで「manage.py」の「makemigraitonsコマンド」や「migrateコマンド」で分割したモデルを認識させることができるようになります。

実装方法まとめ

実装方法を簡単にまとめておきます。

  1. modelsディレクトリを作成する
  2. 作成したmodelsディレクトリに__init__.pyと分割後のモデルのファイルを配置する
  3. モデルクラスを__init__.pyでimportする
  4. モデルクラスのMetaオプションのapp_labelにアプリケーション名を設定する

最後に

今回は普通に開発しているとあまり実装することはないmodels.pyの分割方法について説明しました。モデルの実装量が多く、コードの可読性が低く感じているのであれば、今回のmodels.pyの分割方法を試してみてもらえればと思います。

models.pyの分割以外にもviews.pyDjango REST frameworkで使用するserializers.pyも分割することができるのでまた別の機会に説明したいと思います。

コメントする

メールアドレスが公開されることはありません。