文書の表示以前のリビジョンバックリンク文書の先頭へ この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。 ====== アプリのモデル定義 (django_app/models.py) ====== Django アプリのモデル定義ファイルは、**manage.py startapp** で自動生成された状態では単一の Python モジュールファイルになっている。しかし、ほとんどのプロジェクトではそれなりの規模になると思われるので、モデルクラス 1 つにつき 1 Python ファイルに分けた方が保守性が良いと思う。\\ <WRAP prewrap 100% #mintbl> ^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 に知らせる。 | </WRAP> ===== models.py を 1 クラス 1 ファイルに分割する ===== 標準の models.py は以下のような内容である。\\ <WRAP prewrap 100% #mincode> <code python models.py> from django.db import models # Create your models here. </code> </WRAP> Python はディレクトリに **%%__init__%%.py** (内容は空でもよい) を置くと、ディレクトリ全体をパッケージと見なすようになる。このことを利用して **models.py** を削除して **models** ディレクトリとその中に **%%__init__%%.py** を置くようする。\\ <WRAP prewrap 100% #mintbl> ^django_project ディレクトリ^^^^^^ | + ^django_app ディレクトリ^^^^^ |%%|%%| + |%%__init__%%.py |||このディレクトリが Python パッケージであることを Python に知らせる。 | |%%|%%| + |admin.py |||Django アプリの管理サイトを記述するファイル。 | |%%|%%| + |apps.py ||| | |%%|%%| + ^models ディレクトリ |||Django アプリのモデル定義パッケージ。 | |%%|%%|%%|%%| + |%%__init__%%.py ||このディレクトリが Python パッケージであることを Python に知らせる。 | </WRAP> そして、例えば **media.py** で **Media** モデルを定義する。\\ <WRAP prewrap 100% #mintbl> ^django_project ディレクトリ^^^^^^ | + ^django_app ディレクトリ^^^^^ |%%|%%| + ^models ディレクトリ |||Django アプリのモデル定義パッケージ。 | |%%|%%|%%|%%| + |%%__init__%%.py ||このディレクトリが Python パッケージであることを Python に知らせる。 | |%%|%%|%%|%%| + |media.py ||Media モデルの定義。 | </WRAP> Python のパッケージ内参照 (**from . import name**) を利用して記述すると良い。\\ [[https://docs.python.org/ja/3/tutorial/modules.html#intra-package-references|6. モジュール — Python 3.9.1 ドキュメント - 6.4.2. パッケージ内参照]]\\ <WRAP prewrap 100% #mincode> <code python django_app/models/__init__.py> # -*- encoding: utf-8 -*- from .media import Media </code> </WRAP> **.media** と記述することで **models** パッケージ内の **media** モジュール (media.py) から **import** するように Python に指示できる。\\ <WRAP prewrap 100% #mincode> <code python django_app/models/media.py> # -*- 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制約 </code> </WRAP> ===== トラブルシューティング ===== ==== モデル定義が No module named 'xxxxx' エラーを起こす ==== <WRAP prewrap 100% #result> <code> $ python manage.py Traceback (most recent call last): File "manage.py", line 22, in <module> 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 "<frozen importlib._bootstrap>", line 1006, in _gcd_import File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 728, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File "/home/tomoyan/py3_djangoapp/django_project/django_app/models/__init__.py", line 2, in <module> from media import Media ModuleNotFoundError: No module named 'media' </code> </WRAP> Django アプリのモデル定義パッケージの **%%__init__%%.py** を以下のように記述してはいけない。\\ <WRAP prewrap 100% #mincode> <code python django_app/models/__init__.py> # -*- encoding: utf-8 -*- from media import Media </code> </WRAP> Python のパッケージ内参照 (**from . import name**) を利用して、パッケージ内の **media** モジュールから **import** するように記述する。\\ <WRAP prewrap 100% #mincode> <code python django_app/models/__init__.py> # -*- encoding: utf-8 -*- from .media import Media </code> </WRAP> python/django/model_definition.txt 最終更新: 2020/12/25 06:40by ともやん