アプリケーション—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/applications
移動先:案内検索

アプリケーション

Djangoには、構成を保存してイントロスペクションを提供する、インストールされたアプリケーションのレジストリが含まれています。 また、利用可能なモデルのリストも保持しています。

このレジストリは apps と呼ばれ、 django.apps で利用できます。

>>> from django.apps import apps
>>> apps.get_app_config('admin').verbose_name
'Administration'

プロジェクトとアプリケーション

プロジェクトという用語は、DjangoWebアプリケーションを表します。 プロジェクトのPythonパッケージは、主に設定モジュールによって定義されますが、通常は他のものが含まれています。 たとえば、django-admin startproject mysiteを実行すると、settings.pyurls.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` に追加する必要があります)。


アプリケーションの構成

アプリケーションを構成するには、アプリケーション内にapps.pyモジュールを作成し、そこで AppConfig のサブクラスを定義します。

:setting: `INSTALLED_APPS` にアプリケーションモジュールへの点線のパスが含まれている場合、デフォルトでは、Djangoがapps.pyサブモジュールで AppConfig サブクラスを1つだけ検出すると、アプリケーションのその構成。 この動作は、 AppConfig.defaultFalseに設定することで無効にできます。

apps.pyモジュールに複数の AppConfig サブクラスが含まれている場合、Djangoは AppConfig.defaultTrueである単一のサブクラスを探します。

AppConfig サブクラスが見つからない場合は、基本の AppConfig クラスが使用されます。

または、:setting: `INSTALLED_APPS` に、構成クラスへの点線のパスを含めて、明示的に指定することもできます。

INSTALLED_APPS = [
    ...
    'polls.apps.PollsAppConfig',
    ...
]

アプリケーション作成者向け

「ロックンロール」と呼ばれるプラグイン可能なアプリを作成している場合、管理者に適切な名前を付ける方法は次のとおりです。

# rock_n_roll/apps.py

from django.apps import AppConfig

class RockNRollConfig(AppConfig):
    name = 'rock_n_roll'
    verbose_name = "Rock ’n’ roll"

RockNRollConfigは、:setting: `INSTALLED_APPS`'rock_n_roll'が含まれている場合に自動的にロードされます。 これを防ぐ必要がある場合は、クラス定義で defaultFalseに設定してください。

動作が異なる複数の AppConfig サブクラスを提供できます。 Djangoにデフォルトで使用するものを指示するには、定義で defaultTrueに設定します。 ユーザーがデフォルト以外の構成を選択する場合は、'rock_n_roll'を、:setting: `INSTALLED_APPS` 設定でその特定のクラスへの点線のパスに置き換える必要があります。

AppConfig.name 属性は、この構成が適用されるアプリケーションをDjangoに通知します。 AppConfig APIリファレンスに記載されているその他の属性を定義できます。

AppConfig サブクラスはどこにでも定義できます。 apps.py規則では、:setting: `INSTALLED_APPS` に構成クラスへのパスではなく、アプリケーションモジュールへのパスが含まれている場合に、Djangoがそれらを自動的にロードできるようにします。

ノート

コードがアプリケーションレジストリをアプリケーションの__init__.pyにインポートする場合、名前appsappsサブモジュールと衝突します。 ベストプラクティスは、そのコードをサブモジュールに移動してインポートすることです。 回避策は、レジストリを別の名前でインポートすることです。

from django.apps import apps as django_apps

バージョン3.2での変更:以前のバージョンでは、アプリケーションモジュールのdefault_app_config変数を使用して、デフォルトのアプリケーション構成クラスを識別していました。


アプリケーションユーザー向け

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.pyというサブモジュールにあるプロジェクト固有の構成クラスを示しています。 これは慣例であり、要件ではありません。 AppConfig サブクラスはどこにでも定義できます。

この状況では、:setting: `INSTALLED_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.default

バージョン3.2の新機能。

この属性をFalseに設定して、Djangoが構成クラスを自動的に選択しないようにします。 これは、apps.pyAppConfig サブクラスを1つだけ定義しているが、Djangoがデフォルトでそれを使用したくない場合に役立ちます。

この属性をTrueに設定して、Djangoに構成クラスを自動的に選択するように指示します。 これは、apps.pyが複数の AppConfig サブクラスを定義していて、Djangoがそれらの1つをデフォルトで使用するようにしたい場合に役立ちます。

デフォルトでは、この属性は設定されていません。

AppConfig.default_auto_field

バージョン3.2の新機能。

このアプリ内のモデルに追加する暗黙の主キータイプ。 これを使用して、 AutoField をサードパーティアプリケーションの主キータイプとして保持できます。

デフォルトでは、これは:setting: `DEFAULT_AUTO_FIELD` の値です。


読み取り専用属性

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_migratepost_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. 名前空間パッケージには、実際には1つの場所しかありません(つまり、 複数のディレクトリに分散することはありません。)
  2. アプリケーションの構成に使用される 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_readyFalseに設定すると、アプリレジストリへの入力中、特にモデルをインポートする第2フェーズで、モデルを検索できます。 その場合、get_model()はモデルのインポートと同じ効果があります。 主な使用例は、:setting: `AUTH_USER_MODEL` などの設定でモデルクラスを構成することです。

require_readyFalseの場合、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` の順序ですべてのアプリケーションを処理します。

  1. 最初に、Djangoは:setting: `INSTALLED_APPS` の各アイテムをインポートします。

    アプリケーション構成クラスの場合、Djangoは name 属性で定義されたアプリケーションのルートパッケージをインポートします。 Pythonパッケージの場合、Djangoはapps.pyサブモジュールでアプリケーション構成を探すか、デフォルトのアプリケーション構成を作成します。

    この段階では、コードはモデルをインポートしないはずです。

    つまり、アプリケーションのルートパッケージと、アプリケーション構成クラスを定義するモジュールは、間接的であっても、モデルをインポートしないでください。

    厳密に言えば、Djangoでは、アプリケーション構成が読み込まれるとモデルをインポートできます。 ただし、:setting: `INSTALLED_APPS` の順序に関する不必要な制約を回避するために、この段階ではモデルをインポートしないことを強くお勧めします。

    この段階が完了すると、 get_app_config()などのアプリケーション構成で動作するAPIが使用可能になります。

  2. 次に、Djangoは、各アプリケーションのmodelsサブモジュール(存在する場合)のインポートを試みます。

    アプリケーションのmodels.pyまたはmodels/__init__.pyですべてのモデルを定義またはインポートする必要があります。 そうしないと、この時点でアプリケーションレジストリが完全に読み込まれず、ORMが誤動作する可能性があります。

    この段階が完了すると、 get_model()などのモデルで動作するAPIが使用可能になります。

  3. 最後に、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'を含むように変更します。