> **要約:** > - Django Appは単なるフォルダ分割ではない > - デプロイ単位というよりも、**ビジネスドメインの分離単位**である > - [[DRF]]ではAPI機能ごとのモジュールのように機能するため、そのメリットは明確である > - 一般的なDjango Webアプリでは、最初は必要性を感じにくいかもしれない > - しかし、プロジェクトが大きくなるにつれて、モデル、Admin、テスト、マイグレーションの管理において大きな違いが生まれる > - 適切に設計されたAppは、将来的に他のプロジェクトへ移行できる**再利用可能な資産**となる [[Django]]プロジェクトは、たとえ単一のサーバーにデプロイされる場合でも、`startapp`コマンドを使って複数のAppに分割することができます。 DRFベースのヘッドレスAPIサーバーではこの構造が特に自然ですが、テンプレートベースのDjango WebアプリにおいてもAppの分割は依然として意味を持ちます。 ![Djangoプロジェクト構造の概念図](/media/whitedec/blog_img/fc8aa3e622234c4689779c58a2b8b32e.webp) ## DRFでAppの分割が適している理由 {#sec-f9d183702e4a} * APIの境界が明確になる * `accounts` * `posts` * `billing` * `notifications` * 各Appが独立したAPIのまとまりとして機能する * models * serializers * views / viewsets * permissions * urls * tests * 単一のDRFサーバー内で、複数の機能を標準的な方法で拡張できる * 異なるAppが同じプロジェクト内に存在することで、予期せぬ相乗効果も生まれる * 投稿の公開 → 通知の生成 * 支払いステータス → ユーザー権限の変更 * ユーザー設定 → コンテンツ表示方法の変更 ## 一般的なDjango Webアプリで生じる疑問 {#sec-5b615e36b016} テンプレートベースのDjango Webアプリでは、Appを分割しても結局のところ: * 同じサーバーで実行される * 同じDBを使用する * 同じsettingsを共有する * 同じデプロイ単位でまとめられる * テンプレートの流れも混ざりやすい そのため、小規模なWebアプリでは「わざわざAppを分ける必要があるのか?」と感じるかもしれません。 ## それでもAppを分割する理由 {#sec-ba9a6a819246} * モデルが肥大化するのを防ぐ * Admin画面がドメインごとに整理される * migrationsの履歴がAppごとに分割される * 特定のAppだけをテストしやすくなる * import構造を意識するようになり、スパゲッティコードの防止に役立つ * 将来的に機能を分離したりAPI化する際に、すでに境界が形成されている ## Appは再利用可能な部品になり得る {#sec-0f9d2f3a0f0a} DjangoのApp構造は、機能を**Plug-and-Play可能な部品**のように作成することを可能にします。 プロジェクト内で作成したAppであっても、構造を適切に設計すれば、将来的に別のプロジェクトへ移行しやすくなります。 例えば: * 通知機能 → `notifications` * タグ機能 → `tags` * 決済機能 → `billing` このようなAppを独立して作成しておけば、次のプロジェクトで以下のように再利用できます。 * Appフォルダをコピー * `INSTALLED_APPS`に追加 * 必要なURLを接続 * migrationsを実行 * テンプレートまたは設定のみプロジェクトに合わせて調整 Djangoエコシステムで有名なライブラリも、このような形で提供されています。 * `django-allauth` : 会員登録、ログイン、ソーシャルログイン機能をApp形式で提供 * `django-taggit` : タグ機能を再利用可能なAppとして提供 * `django-tailwind` : Djangoプロジェクト内でTailwind開発環境をApp形式で統合 つまり、Django Appは単に「自分のプロジェクト内のフォルダ」ではなく、適切に設計すれば他のプロジェクトでも再利用できる**機能資産**となり得るのです。 ## 良い分割基準 {#sec-638181ef3b61} Appを分割すべき兆候: * 独立したデータモデルがある * 個別のAdminグループが必要である * 独自のビジネスロジックがある * テストを個別に実行したい * 将来的にAPIまたは別のサービスとして分離される可能性がある * 機能名がサービスドメインで説明できる * 他のプロジェクトでも再利用する可能性がある 例: * `accounts` * `billing` * `notifications` * `support` * `analytics` ## 結論 {#sec-85c066cfb297} [[Django]]プロジェクトにおけるAppの区分は、 > プロジェクトが大規模になった際に、人間が理解できる単位で複雑さを整理する構造 さらに一歩進んで考えれば: > 繰り返し利用できる機能を資産化するDjango流のモジュールシステム [[DRF]]ではこの利点がAPIの境界とよく一致し、すぐに明らかになりますが、 一般的なDjango Webアプリでは、プロジェクトが大きくなったり、複数のプロジェクトを作成し始めたりする際にその価値が顕著になる傾向があります。