====== アプリのモデル定義 (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