python:django:model_definition

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

次のリビジョン
前のリビジョン
python:django:model_definition [2020/12/25 00:33] – 作成 ともやんpython:django:model_definition [2020/12/25 06:40] (現在) – [models.py を 1 クラス 1 ファイルに分割する] ともやん
行 1: 行 1:
 ====== アプリのモデル定義 (django_app/models.py) ====== ====== アプリのモデル定義 (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.1608824010.txt.gz
  • 最終更新: 2020/12/25 00:33
  • by ともやん