====== アプリのモデル定義 (django_app/models.py) ====== Django アプリのモデル定義ファイルは、**manage.py startapp** で自動生成された状態では単一の Python モジュールファイルになっている。しかし、ほとんどのプロジェクトではそれなりの規模になると思われるので、モデルクラス 1 つにつき 1 Python ファイルに分けた方が保守性が良いと思う。\\ ^django_project ディレクトリ^^^^^ | + ^django_app ディレクトリ^^^^ |%%|%%| + |%%__init__%%.py ||このディレクトリが Python パッケージであることを Python に知らせる。 | |%%|%%| + |admin.py ||Django アプリの管理サイトを記述するファイル。 | |%%|%%| + |apps.py ||Django アプリの構成クラスを記述するファイル。 | |%%|%%| + |models.py ||Django アプリのモデル定義ファイル。 | |%%|%%| + |tests.py ||Django アプリのテストを記述するファイル。 | |%%|%%| + |views.py ||Django アプリのビューを記述するファイル。 | |%%|%%| + ^migrations ディレクトリ^^^ |%%|%%|%%|%%| + |%%__init__%%.py |このディレクトリが Python パッケージであることを Python に知らせる。 | ===== models.py を 1 クラス 1 ファイルに分割する ===== 標準の models.py は以下のような内容である。\\ from django.db import models # Create your models here. Python はディレクトリに **%%__init__%%.py** (内容は空でもよい) を置くと、ディレクトリ全体をパッケージと見なすようになる。このことを利用して **models.py** を削除して **models** ディレクトリとその中に **%%__init__%%.py** を置くようする。\\ ^django_project ディレクトリ^^^^^^ | + ^django_app ディレクトリ^^^^^ |%%|%%| + |%%__init__%%.py |||このディレクトリが Python パッケージであることを Python に知らせる。 | |%%|%%| + |admin.py |||Django アプリの管理サイトを記述するファイル。 | |%%|%%| + |apps.py ||| | |%%|%%| + ^models ディレクトリ |||Django アプリのモデル定義パッケージ。 | |%%|%%|%%|%%| + |%%__init__%%.py ||このディレクトリが Python パッケージであることを Python に知らせる。 | そして、例えば **media.py** で **Media** モデルを定義する。\\ ^django_project ディレクトリ^^^^^^ | + ^django_app ディレクトリ^^^^^ |%%|%%| + ^models ディレクトリ |||Django アプリのモデル定義パッケージ。 | |%%|%%|%%|%%| + |%%__init__%%.py ||このディレクトリが Python パッケージであることを Python に知らせる。 | |%%|%%|%%|%%| + |media.py ||Media モデルの定義。 | Python のパッケージ内参照 (**from . import name**) を利用して記述すると良い。\\ [[https://docs.python.org/ja/3/tutorial/modules.html#intra-package-references|6. モジュール — Python 3.9.1 ドキュメント - 6.4.2. パッケージ内参照]]\\ # -*- encoding: utf-8 -*- from .media import Media **.media** と記述することで **models** パッケージ内の **media** モジュール (media.py) から **import** するように Python に指示できる。\\ # -*- encoding: utf-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ class Media(models.Model): media_hash = models.CharField(_('media hash'), max_length = 128, db_index=True) # メディアハッシュ title = models.CharField(_('title'), max_length = 128, blank=True) # タイトル artist = models.CharField(_('artist'), max_length = 128, blank=True) # アーティスト album = models.CharField(_('album'), max_length = 128, blank=True) # アルバム year = models.CharField(_('year'), max_length = 4, blank=True) # 西暦 track = models.IntegerField(_('track'), blank=True) # トラック genre = models.IntegerField(_('genre'), blank=True) # ジャンル file_path = models.CharField(_('file path'), max_length = 128, blank=True) # ファイルパス file_size = models.CharField(_('file size'), max_length = 128, blank=True) # ファイルサイズ time_stamp = models.DateTimeField(_('time stamp'), max_length = 128, blank=True) # 更新日時 youtube_id = models.CharField(_('youtube id'), max_length = 128, blank=True) # YouTube ID # メタ情報 class Meta: app_label = 'django_app' # アプリケーション名 verbose_name = _('Media') # 単数形名称 verbose_name_plural = _('Medias') # 複数形名称 db_table = 'vlc_media' # テーブル名 ordering = ('artist', 'album', 'track',) # ソート列 unique_together = (('media_hash'),) # unique制約 ===== トラブルシューティング ===== ==== モデル定義が No module named 'xxxxx' エラーを起こす ==== $ python manage.py Traceback (most recent call last): File "manage.py", line 22, in main() File "manage.py", line 18, in main execute_from_command_line(sys.argv) File "/home/tomoyan/py3_djangoapp/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line utility.execute() File "/home/tomoyan/py3_djangoapp/lib/python3.7/site-packages/django/core/management/__init__.py", line 377, in execute django.setup() File "/home/tomoyan/py3_djangoapp/lib/python3.7/site-packages/django/__init__.py", line 24, in setup apps.populate(settings.INSTALLED_APPS) File "/home/tomoyan/py3_djangoapp/lib/python3.7/site-packages/django/apps/registry.py", line 114, in populate app_config.import_models() File "/home/pi/py3_musicapp/lib/python3.7/site-packages/django/apps/config.py", line 211, in import_models self.models_module = import_module(models_module_name) File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1006, in _gcd_import File "", line 983, in _find_and_load File "", line 967, in _find_and_load_unlocked File "", line 677, in _load_unlocked File "", line 728, in exec_module File "", line 219, in _call_with_frames_removed File "/home/tomoyan/py3_djangoapp/django_project/django_app/models/__init__.py", line 2, in from media import Media ModuleNotFoundError: No module named 'media' Django アプリのモデル定義パッケージの **%%__init__%%.py** を以下のように記述してはいけない。\\ # -*- encoding: utf-8 -*- from media import Media Python のパッケージ内参照 (**from . import name**) を利用して、パッケージ内の **media** モジュールから **import** するように記述する。\\ # -*- encoding: utf-8 -*- from .media import Media