# Django 5.0.9.dev20240806133106 ドキュメント

# アプリケーション

Django には、設定の保存と調査の手段を提供するインストール済みアプリケーションのレジストリがあり、利用可能な モデル のリストもアクセスできます。

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

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

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

プロジェクト (project) という単語は、Django の web アプリケーションを指します。プロジェクトの Python パッケージは主に settings モジュールで定義されますが、通常は他のファイルも含まれます。たとえば、 `django-admin startproject mysite` を実行すると、`mysite` プロジェクトディレクトリが作成され、その中には `settings.py`、`urls.py`、`asgi.py`、`wsgi.py` などのファイルが含まれる `mysite` Python パッケージが作られます。プロジェクトパッケージは、fixture や CSS、テンプレートなど特定のアプリケーションに束縛されないファイルも含まれることがふつうです。

プロジェクトのルートディレクトリ (`manage.py` があるディレクトリ) は、プロジェクトと一緒にインストールされるすべてのアプリケーションのコンテナとして機能します。

アプリケーション (application) という言葉は、何らかの機能を提供する Python パッケージを意味します。アプリケーションはさまざまなプロジェクトで 再利用する ことができます。

アプリケーションには、モデル、ビュー、テンプレート、テンプレートタグ、静的ファイル、ミドルウェアなどが含まれます。これらは一般に `INSTALLED_APPS` 設定で有効になり、それ以外では URLconf、 `MIDDLEWARE` 設定、テンプレート継承などの仕組みから使われます。

Django のアプリケーションは、フレームワークのさまざまなパーツとやりとりをするコードの集まりであると理解するのは大切です。`Application` オブジェクトのようなものは存在しません。しかしながら、Django がインストール済みのアプリケーションの主に設定やイントロスペクションとやりとりをする必要があることもあります。そのため、インストールアプリケーションごとのメタデータは、アプリケーションレジストリが `AppConfig` インスタンス内に保存しています。

プロジェクトパッケージがアプリケーションとみなされず、モデルなどを持てないといった制限はありません (その場合は `INSTALLED_APPS` に設定を追加する必要があります。)。

## アプリケーションを設定する

アプリケーションを設定するためには、アプリケーション内に `apps.py` モジュールを作成し、そこに `AppConfig` のサブクラスを定義してください。

`INSTALLED_APPS` にアプリケーションモジュールへのドット区切りパスが含まれている場合、デフォルトでは、 Django が `apps.py` サブモジュールの中に `AppConfig` サブクラスを一つでも見つけると、その設定をアプリケーションに使用します。この動作は `AppConfig.default` を `False` に設定すれば無効にできます。

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

もし `AppConfig` のサブクラスが見つからなければ、 `AppConfig` の基底クラスが使用されます。

あるいは、`INSTALLED_APPS` に設定クラスへのドット区切りパスを記述して、明示的に指定することもできます：

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

### アプリケーション開発者向け

例えば、あなたが"Rock 'n' roll"という名前のプラガブルなアプリケーションを作っているとしたら、このようにアプリケーションのadminに適切な名前をつけることになるでしょう:

    # rock_n_roll/apps.py

    from django.apps import AppConfig

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

`RockNRollConfig` は `INSTALLED_APPS` が `'rock_n_roll'` を含むときに自動的に読み込まれます。もしこれを防止したい場合、 `default` を `False` に設定してください。

異なる動作をする `AppConfig` サブクラスを複数用意することができます。Django にどれをデフォルトで使うかを教えるには、 `default` を `True` に設定してください。ユーザがデフォルトでない設定を選びたい場合は、 `INSTALLED_APPS` の設定で `'rock_n_roll'` をその特定のクラスへのドット区切りパスに置き換える必要があります。

`AppConfig.name` 属性は、この設定がどのアプリケーションに適用されるかを Django に伝えます。その他の属性は `AppConfig` API リファレンスで定義できます。

`AppConfig` サブクラスはどこに定義しても構いません。 `apps.py` の規約は、 `INSTALLED_APPS` に設定クラスへのパスではなく、アプリケー ションモジュールへのパスが含まれている場合に、Django がそれらを自動的に読み込むようにしているだけです。

注釈

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

    from django.apps import apps as django_apps

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

`anthology` という名前のプロジェクト内にて "Rock 'n' roll" を利用するものの、その表示は "Jazz Manouche" としたいとします。この場合は設定を以下のようにします。

    # 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` サブクラスはどこに定義しても構いません。

この状況では、外部のアプリケーションに存在するため、設定クラスへのドット区切りパスが `INSTALLED_APPS` に含まれている必要があります。自動的に検出することはできません。

## アプリケーションの設定

class `AppConfig`

  アプリケーション設定オブジェクトはアプリケーションのメタデータを保存します。 いくつかの属性は `AppConfig` サブクラスで設定できます。他の属性は Django によって設定され、読み取り専用です。

### 設定可能な属性

`AppConfig.``name`

  アプリケーションへの Python フルパス、たとえば `'django.contrib.admin'` 。

  この属性は設定がどのアプリケーションに適用されるかを定義します。全ての `AppConfig` サブクラスで設定する必要があります。

  Djangoプロジェクト全体の中で固有である必要があります。

`AppConfig.``label`

  アプリケーション用のショートネーム 例 "'admin'"

  この属性により、2つのアプリケーションのラベルが競合している場合に、アプリケーションのラベルを変更できます。デフォルトは `name` の最後のコンポーネントです。これは有効な Python 識別子でなければなりません。

  Djangoプロジェクト全体の中で固有である必要があります。

  警告

  Changing this attribute after migrations have been applied for an application will result in breaking changes to a project or, in the case of a reusable app, any existing installs of that app. This is because `AppConfig.label` is used in database tables and migration files when referencing an app in the dependencies list.

`AppConfig.``verbose_name`

  人間が読めるアプリケーション名、たとえば "Administration"。

  この属性のデフォルトは `label.title()` です。

`AppConfig.``path`

  アプリケーションディレクトリへのファイルシステムのパス、たとえば `'/usr/lib/pythonX.Y/dist-packages/django/contrib/admin'` 。

  ほとんどの場合、Django は自動的にこれを検出して設定しますが、 `AppConfig` サブクラスのクラス属性として、明示的にオーバーライドを指定することもできます。例えば、アプリパッケージが複数のパスを持つ namespace package である場合などです。

`AppConfig.``default`

  この属性を `False` に設定すると、 Django が自動的に設定クラスを選択しないようにします。これは、`apps.py` で `AppConfig` サブクラスが一つだけ定義されているが、 Django にデフォルトでそれを使わせたくない場合に便利です。

  この属性を `True` に設定すると、 Django に設定クラスを自動的に選択するように指示します。これは、`apps.py` が複数の `AppConfig` サブクラスを定義していて、 Django にそのうちの一つをデフォルトで使わせたい場合に便利です。

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

`AppConfig.``default_auto_field`

  このアプリ内のモデルに追加する暗黙の主キー型です。これを使うと、サードパーティアプリの主キー型を `AutoField` にしておくことができます。

  デフォルトでは `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_migrate` や `post_migrate` といったデータベース関連のシグナルは、 `models` モジュールを持つアプリケーションに対してのみ発行されることに注意してください。

### メソッド

`AppConfig.``get_models`(include_auto_created=False, include_swapped=False)

  このアプリケーションの `Model` クラスのイテラブルを返します。

  アプリのレジストリが完全に入力されている必要があります。

`AppConfig.``get_model`(model_name, require_ready=True)

  与えられた `model_name` を持つ `Model` を返します。 `model_name` は大文字小文字を区別しません。

  このアプリケーションにそのようなモデルが存在しない場合、 `LookupError` を発生させます。

  `require_ready` 引数が `False` に設定されていない限り、アプリのレジストリが完全に登録されている必要があります。 `require_ready` は `apps.get_model()` と全く同じ動作をします。

`AppConfig.``ready`()

  サブクラスはこのメソッドをオーバーライドして、シグナルの登録などの初期化タスクを実行できます。 このメソッドは、レジストリが完全に登録されるとすぐに呼び出されます。

  `AppConfig` クラスが定義されているモジュールレベルでモデルをインポートすることはできませんが、 `import` ステートメントか `get_model()` を使って `ready()` でインポートできます。

  `モデル シグナル` を登録する場合、モデルクラスそのものを使うのではなく、その文字列ラベルで送信者を参照できます。

  実装例:

      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 から一度だけ呼び出されます。しかし、特にインストールされたアプリケーションを操作するテストでは、`ready` は複数回呼び出されるかもしれません。 そのような場合は、idempotent メソッドを書くか、 `AppConfig` クラスにフラグを付けて、一度だけ実行されるべきコードの再実行を防いでください。

### アプリとしての名前空間 (namespace) パッケージ

`__init__.py` ファイルを持たない Python パッケージは "namespace package" と呼ばれ、 `sys.path` 上の異なる場所にある複数のディレクトリにまたがっている可能性があります (PEP 420 を参照してください)。

Djangoアプリケーションは(設定に応じて)、Djangoがテンプレートや静的アセットを探す単一のベースファイスシステムパスを必要とします。したがって、名前空間パッケージは以下のいずれかが真である場合にのみ、Django アプリケーションになることができます。

1. 名前空間パッケージは実際には単一の場所にしか存在しません(つまり、複数のディレクトリに分散していないということです)。
2. アプリケーションの設定に使われる `AppConfig` クラスには `path` クラス属性があり、これは Django がアプリケーションの単一のベースパスとして使う絶対ディレクトリパスです。

これらの条件のどちらも満たさない場合、Django は `ImproperlyConfigured` を発生させます。

## アプリケーションレジストリ

`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` を持つ `Model` を返します。 ショートカットとして、このメソッドは `app_label.model_name` 形式の引数も受け付けます。 `model_name` は大文字小文字を区別しません。

  そのようなアプリケーションやモデルが存在しない場合 `LookupError` を発生させます。 正確に1つのドットを含まない単一の引数で呼び出された場合、 `ValueError` を発生させます。

  `require_ready` 引数が `False` に設定されていない限り、アプリのレジストリが完全に登録されている必要があります。

  `require_ready` を `False` に設定することで、 アプリのレジストリを作成している間 、特にモデルをインポートする2番目のフェーズでモデルを検索できます。この場合、`get_model()` はモデルをインポートするのと同じ効果があります。主なユースケースは、モデルクラスを `AUTH_USER_MODEL` のような設定で構成することです。

  `require_ready` が `False` の場合、`get_model()` はアプリのレジストリが完全に入力されるまで、完全に機能しない (例えば、逆アクセサが存在しない) モデルクラスを返します。このため、常に `require_ready` をデフォルト値の `True` にしておくことをお勧めします。

## 初期化プロセス

### アプリケーションはどう読み込まれるか

Django が起動すると、 `django.setup()` がアプリケーションレジストリの入力を行います。

`setup`(set_prefix=True)

  下記によって Django を設定します：

  - 設定を読み込む。
  - ロギングをセットアップする。
  - `set_prefix` が True の場合、URLリゾルバのスクリプトのプレフィックスを、 定義されていれば `FORCE_SCRIPT_NAME` に、そうでなければ `/` に設定する。
  - アプリケーション・レジストリを初期化する。

  この関数は以下の場合に自動で呼び出されます：

  - Django の ASGI や WSGI サポート経由で HTTP サーバを実行する場合。
  - 管理コマンドを起動するとき。

  それ以外の場合、たとえばプレーンなPythonスクリプトでは、明示的に呼び出す必要があります。

  Changed in Django 5.0:

  アプリのレジストリが完全に登録される前にアプリがデータベースとやり取りをすると `RuntimeWarning` を発生させます。

アプリケーションレジストリは 3 段階で初期化されます。それぞれの段階で、 Django は全てのアプリケーションを `INSTALLED_APPS` の順番で処理します。

1. まず Django は `INSTALLED_APPS` の各アイテムをインポートします。

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

   "この時点では、どのモデルもインポートしてはいけません！"

   言い換えると、アプリケーションのルートパッケージとアプリケーションの configuration クラスを定義するモジュールは、間接的であってもモデルをインポートすべきではありません。

   厳密に言えば、Django はアプリケーションの設定が読み込まれた時点でモデルのインポートを許可します。しかし、 `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` モジュールの自動検出を自動的に行います。これを防ぐには、 `INSTALLED_APPS` に `'django.contrib.admin'` の代わりに `'django.contrib.admin.apps.SimpleAdminConfig'` を含めるように変更してください。

- `RuntimeWarning: Accessing the database during app initialization is discouraged.` この警告は、アプリが準備完了前に実行されるデータベースクエリに対して発生します。例えば、モジュールのインポート中や `AppConfig.ready()` メソッド内などです。このような早すぎるデータベースクエリは、すべての管理コマンドの起動時に実行されるため、プロジェクトの起動が遅くなったり、古いデータがキャッシュされたり、マイグレーションが保留中の場合には失敗する可能性があるため、推奨されません。

  たとえば、よくある間違いは、フォームフィールドの選択肢を入力するためにデータベースクエリを作成することです：

      class LocationForm(forms.Form):
          country = forms.ChoiceField(choices=[c.name for c in Country.objects.all()])

  上の例では、 `QuerySet` がイテレートされるため、 `Country.objects.all()` からのクエリがモジュールのインポート時に実行されます。警告を回避するには、代わりに `ModelChoiceField` を使用します：

      class LocationForm(forms.Form):
          country = forms.ModelChoiceField(queryset=Country.objects.all())

  この警告を引き起こしたコードを見つけやすくするために、Pythonで 警告をエラーとして扱う ことでスタックトレースを明らかにできます。例えば、`python -Werror manage.py shell` というコマンドを使用します。