📚

【Django】INSTALLED_APPSにアプリケーションを登録する意味について【初心者向けの記事】

2025/01/14に公開

もう正月から2週間!?
と、愕然としています。

こんにちは、
ワニかず@40歳 出戻りエンジニアです。

以前、こちらでご説明した、「Djangoプロジェクトを作成する」
https://zenn.dev/40_comeback_eng/articles/29c306f656babe
を実行すると、
作成されたファイルの中に「settings.py」
が存在すると思うのですが、

その中に
「INSTALLED_APPS」という記述があります。

そもそも、この設定は何なのか?
を調べたのでまとめました。

INSTALLED_APPSへ設定を記述する意味

「INSTALLED_APPSへ設定を記述する、という作業」=
「Djangoアプリケーションの登録」という作業
で、登録が必要な理由は以下の通りです。

Djangoにアプリケーションの存在を認識させるため

  • どのアプリケーションが使用可能なのかをDjangoに伝える
  • これがないと、Djangoはそのアプリケーションの存在を認識できない

データベース関連の処理のため

  • マイグレーション(データベースの構造変更)を実行する際、どのアプリケーションのモデルを対象にするか判断できる
  • python manage.py makemigrations を実行したとき、登録されているアプリケーションのモデルの変更のみを検出できる

テンプレートの検索のため

  • Djangoは登録されたアプリケーションの中からテンプレートファイル(テンプレートとは、HTMLを動的に生成するためのファイル)を探す
    例:myapp1/templates/ ディレクトリ内のテンプレートを使えるようにする

静的ファイル(CSS、JavaScript等)の検索のため

python manage.py collectstatic コマンドで、登録されたアプリケーションの静的ファイルを収集

具体例:

python
INSTALLED_APPS = [
    'myapp1',  # これを登録しないと...
    'django.contrib.admin',
    # ...
]

このmyapp1を登録しないと:

  • myapp1のモデルのマイグレーションが実行されない
  • myapp1のテンプレートが見つからない
  • myapp1の静的ファイルが収集されない
  • 管理画面でmyapp1のモデルが表示されない

などの問題が発生します。つまり、
INSTALLED_APPSへの登録は、
アプリケーションをDjangoのシステムに
「組み込む」ための必須の設定作業だと言えます。

INSTALLED_APPSへ設定できるのは?

INSTALLED_APPS には、

  • アプリケーション構成クラスを直接指定する
  • 使用するパッケージを設定する
    というルールになってます。

ここで、
「アプリケーション構成クラス」とは何ぞや?
という疑問が生まれてきます。

アプリケーション構成クラスとは?

  • AppConfigクラス
  • AppConfigクラスの派生クラス
    です。

ですので、自動的に作成される
「settings.py」
に自動で記述されている

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

も、それぞれAppConfigを継承したクラスを持っています。

AppConfigクラスは、
Djangoがアプリケーションの設定を管理するために用意した特別なクラス
で、
Djangoアプリケーションの設定と動作を制御するための中心的なクラスです。
その具体的な役割と特徴は、

  1. アプリケーションの名前空間の管理
python
class MyAppConfig(AppConfig):
    name = 'myapp'  # これが名前空間。Djangoがこのアプリを識別するためのパス
    label = 'my_app'  # アプリの短い名前(省略可)
    verbose_name = 'My Application'  # 管理画面などでの表示名

これにより、Djangoは異なるアプリケーション間の
名前の衝突を防ぎ、適切にアプリケーションを識別できます。

  1. シグナルの登録
python
class MyAppConfig(AppConfig):
    def ready(self):
        # シグナルの登録
        from django.db.models.signals import post_save
        from .models import MyModel
        from .signals import my_callback
        
        post_save.connect(my_callback, sender=MyModel)

アプリケーション起動時にシグナル(イベントハンドラ)を登録できます。
これにより、特定のイベント(モデルの保存など)が発生したときに
自動的に処理を実行できます。

  1. 起動時の初期化処理の実行
python
class MyAppConfig(AppConfig):
    def ready(self):
        # アプリケーション起動時に必要な初期化処理
        self.init_cache()  # キャッシュの初期化
        self.load_settings()  # 設定の読み込み
        self.register_periodic_tasks()  # 定期タスクの登録

アプリケーションが起動するときに必要な初期化処理をここで行います。

  1. アプリケーションのメタデータの提供
python
class MyAppConfig(AppConfig):
    name = 'myapp'
    verbose_name = 'My Application'
    version = '1.0.0'
    author = 'Your Name'
    description = 'This is my awesome app'
    
    def get_models(self):
        # このアプリのすべてのモデルを返す
        return self.models.values()
  1. モデルの追跡と管理
python
class MyAppConfig(AppConfig):
    def ready(self):
        # このアプリに属するすべてのモデルを取得
        models = self.get_models()
        # 特定のモデルを取得
        User = self.get_model('User')
        # モデルの関係性を管理

アプリケーションに属するすべてのモデルを追跡し、
それらの関係性を管理します。

↑このメリットがよくわからなかったので、
もう少し深堀して調べてみました。

「アプリケーションに属するすべてのモデルを追跡し、関係性を管理」のメリット例

Djangoの管理画面(admin)の動作が、
この機能の恩恵を受けている最も分かりやすい例です。

  • 具体例
python
# blog/models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    bio = models.TextField()

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    text = models.TextField()

このモデル構造で、以下のようなことが自動的に行われます

  1. 管理画面での連鎖削除の制御
    管理画面でAuthorを削除しようとすると、Djangoは自動的に
  • 「このAuthorに紐づくPostが○件あります」という警告を表示
  • 削除するとそれらのPostも削除されることを通知
    これはAppConfigがモデル間の関係を追跡しているからこそできる機能です
  1. 関連データの一括処理
python
# views.py
def delete_author(request, author_id):
    author = Author.objects.get(id=author_id)
    # この1行で:
    # - 著者の削除
    # - 著者の投稿の削除
    # - その投稿へのコメントの削除
    # が適切な順序で実行される
    author.delete()

これも、AppConfigがモデル間の依存関係を
把握しているからこそ、正しい順序で削除が実行されます。

  1. 逆参照の自動設定
python
# 著者の全投稿を取得
author = Author.objects.get(id=1)
# post_setという逆参照が自動的に使える
all_posts = author.post_set.all()

AppConfigがモデル間の関係を管理しているおかげで、
このような便利な逆参照が自動的に設定されます。

この機能がないと、

  • モデル間の関係を手動で追跡する必要がある
  • 削除時の整合性を自分で確認・制御しなければならない
  • 逆参照の設定を手動で行う必要がある

など、多くの作業を開発者が手動で行わなければならなくなります。
つまり、AppConfigのモデル管理機能は、
開発者の労力を大幅に削減し、ミスを防ぐ重要な役割を果たしているのです。

Discussion