# 目錄結構

由於大多數網路上及教學,專案大都只含一個 app,而實際上多數商用專案及實際情況都會需多管理多個 apps,這邊就來看看多個 app 的整個專案結構會變如何

先看一開始還沒有拆分多個 Apps 前的 Django 專案結構:

my_project/

├── manage.py                    # Django CLI 入口
├── requirements.txt              # Python 依賴套件

├── backend/                      # Django 專案設定
   ├── __init__.py
   ├── asgi.py                   # ASGI 入口 (WebSocket)
   ├── settings.py                # Django 設定檔
   ├── urls.py                    # 全域路由
   ├── wsgi.py                    # WSGI 入口 (部署)

├── api/                           # 單一 API App (未拆分多個 apps)
   ├── __init__.py
   ├── admin.py                   # Django Admin 註冊
   ├── apps.py                     # Django App 設定
   ├── base_views.py               # 共用的視圖函數
   ├── models.py                   # 所有資料表定義
   ├── serializer.py               # Django REST Framework (DRF) 序列化
   ├── tests.py                    # 測試檔案
   ├── migrations/                 # 資料庫遷移檔案
   ├── urls/
        ├── product_urls.py        # 路由目錄 (可能用來拆分 API 路由)
   ├── views/
        ├── product_views.py       # API 視圖目錄

多新增 blog 這個 apps 後的專案結構:

my_project/

├── manage.py
├── README.md
├── requirements.txt
├── .gitignore
├── .env
├── backend/             # Main project folder
   ├── __init__.py
   ├── settings.py         # Or a settings/ folder with separate files (base.py, dev.py, prod.py)
   ├── urls.py
   ├── wsgi.py
   ├── asgi.py│
├── api/                   # (apps) Directory for all Django apps
   ├── __init__.py         # Makes 'apps' a Python package
   ├── products/               # (app1) 產品管理 App
   ├── migrations/
   ├── __init__.py
   ├── admin.py
   ├── apps.py
   ├── models.py
   ├── tests.py
   ├── views.py
   ├── urls.py         # App-specific URL configuration
   └── blog/               # (app2) 文章管理 App
       ├── migrations/
       ├── __init__.py
       ├── admin.py
       ├── apps.py
       ├── models.py
       ├── tests.py
       ├── views.py
       ├── urls.py
└── static/                 # Global static files (e.g., CSS, JavaScript, images)
    ├── css/
    ├── js/
    └── images/

原本只打算單純的透過在 urls 以及 views 目錄下命名不同的 Ex: product_views.pyblog_views.py 來區分不同的 API 視圖,

  • 但考慮到專案未來擴展性, models.py 可能會變得非常雜亂及龐大,且不同的資料表欄位可能會衝突,Ex: product 與 blog 都會有 Tag 資料表,這樣會造成混淆及不易管理
  • 因此決定將不同的功能拆分成不同的 apps,並各自管理自己的 models.pyviews.pyurls.py

# 專案目錄結構差別圖

dir_before_after

# 程式修改

# apps

由於大幅移動的目錄結構,所以再次執行 python manage.py runserver 時會出現找不到模組的錯誤 ModuleNotFoundError: No module named 'api.apps' 是正常的,這時候就需要進行一些程式碼的調整

首先 apps 的部分就跟先前稍微不同的,大多都是路徑的調整而已,像是 apps.py 就需要調整成 api.products,這樣 Django 才能正確的辨識到這個 app

產品的:

# api/products/apps.py

# class ApiConfig(AppConfig):
#     default_auto_field = 'django.db.models.BigAutoField'
#     name = 'api'

class ApiConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'api.products'

文章的

# api/blog/apps.py

class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'api.blog'
    verbose_name = "文章管理"  # 🔹 Django Admin 會顯示「文章管理」

# settings

然後在 INSTALLED_APPS 中也多註冊新增的 app

# backend/settings.py
INSTALLED_APPS = [
    ...
    # 註冊 api(後端資料夾名稱) app
    'api.products.apps.ProductsConfig',
    'api.blog.apps.BlogConfig',
    # DRF
    'rest_framework',
    # cors
    'corsheaders',
]

# urls

然後在專案的路由總管 urls.py 中也要調整路由的設定成我們更新完的路徑

# api/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),

    path('api/products/', include('api.products.urls')),  # 產品 API
    path('api/blog/', include('api.blog.urls')),  # 部落格 API
]

# 測試兩個 apps 是否都能正常運行

解決所有路徑問題後,就可以來測試兩個 apps 是否都能正常運行

# 文章管理後端

# views

先簡單的在 blog 中新增一個 API 視圖,並回傳一個 JSON

# api/blog/views.py

from django.http import JsonResponse
from django.views import View

class BlogPostListView(View):
    def get(self, request):
        data = {
            "message": "HEEEEEEEEEEEELLLLOOOOOOOOOOOOOO~~~~~ (BlogPostListView)",
            "posts": []
        }
        return JsonResponse(data)

# urls

from django.urls import path
from .views import BlogPostListView

urlpatterns = [
    path('', BlogPostListView.as_view(), name='blog-list'),
]

# 成功畫面

blog_response

# 產品管理後端

在產品的部分主要會有的問題就是由於先前已經 migrate 過資料表,而 Django 會使用 app_label_modelname 的格式來命名資料表,所以會有 django.db.utils.OperationalError: (1050, "Table 'products_product' already exists") 找不到指定資料表的錯誤

所以先去 MySQL 中刪舊的 api_product..api_productimage... 資料表

DROP TABLE api_product,...;

再進行一次 migrate 並新增資料就能正常啟動服務了

# 成功畫面

product_response

請我喝[茶]~( ̄▽ ̄)~*

Young 微信支付

微信支付

Young 支付寶

支付寶