アプリケーション
Djangoには、構成を保存してイントロスペクションを提供する、インストールされたアプリケーションのレジストリが含まれています。 また、利用可能なモデルのリストも保持しています。
このレジストリは apps と呼ばれ、 django.apps で利用できます。
>>> from django.apps import apps
>>> apps.get_app_config('admin').verbose_name
'Administration'
プロジェクトとアプリケーション
プロジェクトという用語は、DjangoWebアプリケーションを表します。 プロジェクトのPythonパッケージは、主に設定モジュールによって定義されますが、通常は他のものが含まれています。 たとえば、django-admin startproject mysite
を実行すると、settings.py
、urls.py
を含むmysite
Pythonパッケージを含むmysite
プロジェクトディレクトリが取得されます。 、asgi.py
およびwsgi.py
。 プロジェクトパッケージは、特定のアプリケーションに関連付けられていないフィクスチャ、CSS、テンプレートなどを含むように拡張されることがよくあります。
プロジェクトのルートディレクトリ(manage.py
を含むディレクトリ)は通常、個別にインストールされていないプロジェクトのすべてのアプリケーションのコンテナです。
アプリケーションという用語は、いくつかの機能セットを提供するPythonパッケージを表します。 アプリケーションは、さまざまなプロジェクトで再利用できます。
アプリケーションには、モデル、ビュー、テンプレート、テンプレートタグ、静的ファイル、URL、ミドルウェアなどの組み合わせが含まれます。 これらは通常、:setting: `INSTALLED_APPS` 設定を使用してプロジェクトに接続され、オプションでURLconfs、:setting:` MIDDLEWARE` 設定、またはテンプレート継承などの他のメカニズムを使用して接続されます。
Djangoアプリケーションは、フレームワークのさまざまな部分と相互作用する一連のコードであることを理解することが重要です。 Application
オブジェクトのようなものはありません。 ただし、主に構成とイントロスペクションのために、Djangoがインストールされたアプリケーションと対話する必要がある場所がいくつかあります。 そのため、アプリケーションレジストリは、インストールされている各アプリケーションの AppConfig インスタンスにメタデータを保持します。
プロジェクトパッケージもアプリケーションと見なすことができず、モデルなどを含めることができないという制限はありません。 (:setting: `INSTALLED_APPS` に追加する必要があります)。
アプリケーションの構成
アプリケーションを構成するには、 AppConfig をサブクラス化し、そのサブクラスへの点線のパスを:setting: `INSTALLED_APPS` に配置します。
:setting: `INSTALLED_APPS` にアプリケーションモジュールへの点線のパスが含まれている場合、Djangoはそのモジュール内のdefault_app_config
変数をチェックします。
定義されている場合、それはそのアプリケーションの AppConfig サブクラスへの点線のパスです。
default_app_config
がない場合、Djangoは基本の AppConfig クラスを使用します。
default_app_config
を使用すると、django.contrib.admin
などのDjango1.7より前のアプリケーションで、ユーザーが:setting: `INSTALLED_APPS` を更新しなくても、 AppConfig 機能にオプトインできます。 ]。
新しいアプリケーションはdefault_app_config
を避ける必要があります。 代わりに、適切な AppConfig サブクラスへの点線のパスを:setting: `INSTALLED_APPS` で明示的に構成する必要があります。
アプリケーションユーザー向け
anthology
というプロジェクトで「ロックンロール」を使用しているが、代わりに「ジャズマヌーシュ」として表示したい場合は、独自の構成を提供できます。
# anthology/apps.py
from rock_n_roll.apps import RockNRollConfig
class JazzManoucheConfig(RockNRollConfig):
verbose_name = "Jazz Manouche"
# anthology/settings.py
INSTALLED_APPS = [
'anthology.apps.JazzManoucheConfig',
# ...
]
繰り返しますが、apps
と呼ばれるサブモジュールでプロジェクト固有の構成クラスを定義することは慣例であり、要件ではありません。
アプリケーション構成
- class AppConfig
- アプリケーション構成オブジェクトは、アプリケーションのメタデータを格納します。 一部の属性は、 AppConfig サブクラスで構成できます。 その他はDjangoによって設定され、読み取り専用です。
構成可能な属性
- AppConfig.name
アプリケーションへの完全なPythonパス(例:
'django.contrib.admin'
。この属性は、構成が適用されるアプリケーションを定義します。 すべての AppConfig サブクラスで設定する必要があります。
Djangoプロジェクト全体で一意である必要があります。
- AppConfig.label
アプリケーションの短縮名。例:
'admin'
この属性を使用すると、2つのアプリケーションのラベルが競合している場合に、アプリケーションのラベルを変更できます。 デフォルトでは、
name
の最後のコンポーネントになります。 有効なPython識別子である必要があります。Djangoプロジェクト全体で一意である必要があります。
- AppConfig.verbose_name
アプリケーションの人間が読める名前。例: "管理"。
この属性のデフォルトは
label.title()
です。
- AppConfig.path
アプリケーションディレクトリへのファイルシステムパス(例:
'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'
。ほとんどの場合、Djangoはこれを自動的に検出して設定できますが、 AppConfig サブクラスのクラス属性として明示的なオーバーライドを提供することもできます。 いくつかの状況では、これが必要です。 たとえば、アプリパッケージが複数のパスを持つ名前空間パッケージである場合。
読み取り専用属性
- AppConfig.module
- アプリケーションのルートモジュール、例:
<module 'django.contrib.admin' from 'django/contrib/admin/__init__.py'>
。
- AppConfig.models_module
モデルを含むモジュール、例えば
<module 'django.contrib.admin.models' from 'django/contrib/admin/models.py'>
。アプリケーションに
models
モジュールが含まれていない場合は、None
の可能性があります。 pre_migrate や post_migrate などのデータベース関連のシグナルは、models
モジュールを備えたアプリケーションに対してのみ発行されることに注意してください。
メソッド
- AppConfig.get_models()
このアプリケーションの Model クラスの反復可能オブジェクトを返します。
アプリのレジストリが完全に入力されている必要があります。
- AppConfig.get_model(model_name, require_ready=True)
指定された
model_name
でモデルを返します。model_name
では大文字と小文字は区別されません。このアプリケーションにそのようなモデルが存在しない場合は、
LookupError
を発生させます。require_ready
引数がFalse
に設定されていない限り、アプリレジストリに完全に入力する必要があります。require_ready
は、 apps.get_model()とまったく同じように動作します。
- AppConfig.ready()
サブクラスは、このメソッドをオーバーライドして、シグナルの登録などの初期化タスクを実行できます。 レジストリが完全に入力されるとすぐに呼び出されます。
AppConfig クラスが定義されているモジュールレベルでモデルをインポートすることはできませんが、
import
ステートメントまたはのいずれかを使用してready()
にモデルをインポートできます。 get_model()。モデルシグナルを登録している場合は、モデルクラス自体を使用する代わりに、文字列ラベルで送信者を参照できます。
例:
from django.apps import AppConfig from django.db.models.signals import pre_save class RockNRollConfig(AppConfig): # ... def ready(self): # importing model classes from .models import MyModel # or... MyModel = self.get_model('MyModel') # registering signals with the model's string label pre_save.connect(receiver, sender='app_label.MyModel')
警告
上記のようにモデルクラスにアクセスできますが、 ready()実装でデータベースと対話することは避けてください。 これには、クエリを実行するモデルメソッド( save()、 delete()、マネージャーメソッドなど)と、
django.db.connection
を介した生のSQLクエリが含まれます。 ready()メソッドは、すべての管理コマンドの起動中に実行されます。 たとえば、テストデータベースの構成が本番環境の設定とは別であっても、manage.py test
は本番環境データベースに対していくつかのクエリを実行します。ノート
通常の初期化プロセスでは、
ready
メソッドはDjangoによって1回だけ呼び出されます。 ただし、一部のコーナーケース、特にインストールされているアプリケーションをいじっているテストでは、ready
が複数回呼び出される場合があります。 その場合は、べき等メソッドを作成するか、AppConfig
クラスにフラグを設定して、1回だけ実行する必要のあるコードが再実行されないようにします。
アプリとしての名前空間パッケージ
__init__.py
ファイルのないPythonパッケージは「名前空間パッケージ」と呼ばれ、sys.path
の異なる場所にある複数のディレクトリに分散する場合があります( PEP 420 [X183X ])。
Djangoアプリケーションには、Django(構成に応じて)がテンプレートや静的アセットなどを検索する単一のベースファイルシステムパスが必要です。 したがって、名前空間パッケージは、次のいずれかに該当する場合にのみDjangoアプリケーションになる可能性があります。
- 名前空間パッケージには、実際には1つの場所しかありません(つまり、 複数のディレクトリに分散することはありません。)
- アプリケーションの構成に使用される AppConfig クラスには、 path クラス属性があります。これは、Djangoがアプリケーションの単一のベースパスとして使用する絶対ディレクトリパスです。
これらの条件のいずれも満たされない場合、Djangoは ImpproperlyConfigured を発生させます。
アプリケーションレジストリ
- apps
- アプリケーションレジストリは、次のパブリックAPIを提供します。 以下にリストされていないメソッドはプライベートと見なされ、予告なしに変更される場合があります。
- apps.ready
- レジストリが完全に入力され、すべての AppConfig.ready()メソッドが呼び出された後、
True
に設定されるブール属性。
- apps.get_app_configs()
- AppConfig インスタンスの反復可能オブジェクトを返します。
- apps.get_app_config(app_label)
- 指定された
app_label
を持つアプリケーションの AppConfig を返します。 そのようなアプリケーションが存在しない場合、LookupError
を発生させます。
- apps.is_installed(app_name)
- 指定された名前のアプリケーションがレジストリに存在するかどうかを確認します。
app_name
はアプリのフルネームです。例:'django.contrib.admin'
。
- apps.get_model(app_label, model_name, require_ready=True)
指定された
app_label
およびmodel_name
を持つモデルを返します。 ショートカットとして、このメソッドはapp_label.model_name
の形式の単一の引数も受け入れます。model_name
では大文字と小文字は区別されません。そのようなアプリケーションまたはモデルが存在しない場合、
LookupError
を発生させます。 正確に1つのドットを含まない単一の引数で呼び出されると、ValueError
が発生します。require_ready
引数がFalse
に設定されていない限り、アプリレジストリに完全に入力する必要があります。require_ready
をFalse
に設定すると、アプリレジストリへの入力中、特にモデルをインポートする第2フェーズで、モデルを検索できます。 その場合、get_model()
はモデルのインポートと同じ効果があります。 主な使用例は、:setting: `AUTH_USER_MODEL` などの設定でモデルクラスを構成することです。require_ready
がFalse
の場合、get_model()
は、アプリレジストリが完全に読み込まれるまで、完全に機能しない可能性がある(たとえば、リバースアクセサーがない可能性がある)モデルクラスを返します。 このため、可能な限りrequire_ready
をデフォルト値のTrue
のままにしておくことをお勧めします。
初期化プロセス
アプリケーションのロード方法
Djangoが起動すると、 django.setup()がアプリケーションレジストリへの入力を担当します。
- setup(set_prefix=True)
次の方法でDjangoを構成します。
設定を読み込んでいます。
ロギングの設定。
set_prefix
がTrueの場合、URLリゾルバースクリプトプレフィックスを:setting: `FORCE_SCRIPT_NAME` (定義されている場合)に設定するか、/
に設定します。アプリケーションレジストリを初期化しています。
この関数は自動的に呼び出されます。
DjangoのWSGIサポートを介してHTTPサーバーを実行する場合。
管理コマンドを呼び出すとき。
他の場合、たとえばプレーンなPythonスクリプトでは、明示的に呼び出す必要があります。
アプリケーションレジストリは3段階で初期化されます。 各段階で、Djangoは:setting: `INSTALLED_APPS` の順序ですべてのアプリケーションを処理します。
最初に、Djangoは:setting: `INSTALLED_APPS` の各アイテムをインポートします。
アプリケーション構成クラスの場合、Djangoは name 属性で定義されたアプリケーションのルートパッケージをインポートします。 Pythonパッケージの場合、Djangoはデフォルトのアプリケーション構成を作成します。
この段階では、コードはモデルをインポートしないはずです。
つまり、アプリケーションのルートパッケージと、アプリケーション構成クラスを定義するモジュールは、間接的であっても、モデルをインポートしないでください。
厳密に言えば、Djangoでは、アプリケーション構成が読み込まれるとモデルをインポートできます。 ただし、:setting: `INSTALLED_APPS` の順序に関する不必要な制約を回避するために、この段階ではモデルをインポートしないことを強くお勧めします。
この段階が完了すると、 get_app_config()などのアプリケーション構成で動作するAPIが使用可能になります。
次に、Djangoは、各アプリケーションの
models
サブモジュール(存在する場合)のインポートを試みます。アプリケーションの
models.py
またはmodels/__init__.py
ですべてのモデルを定義またはインポートする必要があります。 そうしないと、この時点でアプリケーションレジストリが完全に読み込まれず、ORMが誤動作する可能性があります。この段階が完了すると、 get_model()などのモデルで動作するAPIが使用可能になります。
最後に、Djangoは各アプリケーション構成の ready()メソッドを実行します。
トラブルシューティング
初期化中に発生する可能性のある一般的な問題は次のとおりです。
AppRegistryNotReady :これは、アプリケーション構成をインポートするか、モデルモジュールがアプリレジストリに依存するコードをトリガーするときに発生します。
たとえば、 gettext()は、アプリレジストリを使用して、アプリケーションの翻訳カタログを検索します。 インポート時に翻訳するには、代わりに gettext_lazy()が必要です。 ( gettext()の使用はバグになります。これは、アクティブな言語に応じて、リクエストごとではなく、インポート時に翻訳が行われるためです。)
モデルモジュールでインポート時にORMを使用してデータベースクエリを実行すると、この例外もトリガーされます。 すべてのモデルが利用可能になるまで、ORMは正しく機能できません。
この例外は、スタンドアロンのPythonスクリプトで django.setup()を呼び出すのを忘れた場合にも発生します。
ImportError: cannot import name ...
これは、インポートシーケンスがループで終了した場合に発生します。このような問題を排除するには、モデルモジュール間の依存関係を最小限に抑え、インポート時の作業をできるだけ少なくする必要があります。 インポート時にコードが実行されないようにするには、コードを関数に移動して結果をキャッシュします。 コードは、最初に結果が必要になったときに実行されます。 この概念は「遅延評価」として知られています。
django.contrib.admin
は、インストールされているアプリケーションのadmin
モジュールの自動検出を自動的に実行します。 これを防ぐには、:setting: `INSTALLED_APPS` を'django.contrib.admin'
ではなく'django.contrib.admin.apps.SimpleAdminConfig'
を含むように変更します。