iT邦幫忙

2025 iThome 鐵人賽

DAY 26
1

前面內容主要著重於前端網頁的開發,針對後端部分著墨較少,但因為前端時常需處理API請求,若完全不懂後端的東西,會不知道該如何請求網址,並且若有想要更改資料模型的話,以符合前端開發需求,還是要對後端的東西有所了解。

之後僅簡單介紹後端Django的專案架構,及該如何解讀資料模型。

在接觸過Vue的專案架構後,其實回頭去看Django專案架構,應該不會感到太陌生,參考如下:

my-project/
├─ server/                     # Django專案
│  ├─ manage.py
│  ├─ apps/                    # 專案層
│  │  ├─ settings.py
│  │  ├─ urls.py
│  │  ├─ wsgi.py
│  │  ├─ asgi.py
│  │  └─ __init__.py
│  ├─ employee/                # App層
│  │  ├─ urls.py
│  │  ├─ views.py
│  │  ├─ serializers.py
│  │  ├─ models.py
│  │  └─ migrations/
│  └─ requirements.txt
│
└─ client/                     # Vue 專案
   ├─ src/
   │  ├─ router/
   │  ├─ views/
   │  ├─ components/
   │  ├─ store/
   │  ├─ common/
   │  ├─ main.js 
   │  └─ App.vue
   └─ public/
  • 在前端,乃採用src/main.js啟動Vue app,而在後端,則是由manage.py作為Django的指令入口,啟動開發伺服器。

  • 啟動伺服器,所參考的設定值,將放置於apps/settings.py,內容包括專案位置等基本設定、安全性、已安裝的app清單、DRF設定、資料庫設定等,參考如下:

    # apps/settings.py
    # 設定專案的根目錄(通常是manage.py所在位置)
    BASE_DIR = Path(__file__).resolve().parent.parent
    
    # 使用django-environ管理環境變數(DEBUG、SECRET_KEY、資料庫帳密)
    env = environ.Env(DEBUG=(bool, False))
    ENV_FILE = BASE_DIR / 'envs' / env('ENV_FILE', default='dev.env')
    env.read_env(str(ENV_FILE))
    
    # 用於加密session、簽名等(正式環境必須保密)
    SECRET_KEY = env('SECRET_KEY', default='unsafe-secret-key')
    # 開發模式顯示錯誤詳細訊息,正式環境必須關閉
    DEBUG = env('DEBUG')
    # 白名單,允許哪些網域訪問
    ALLOWED_HOSTS = ['localhost', '127.0.0.1']
    
    # 所安裝的內建Django App、自訂App及第三方套件
    INSTALLED_APPS = [
        'django.contrib.admin',           # 後台管理
        'django.contrib.auth',            # 認證系統
        'django.contrib.contenttypes', 
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django_extensions',              # 開發工具
        'rest_framework',                 # DRF API
        'employee',                       # 自訂App
        'corsheaders'                     # 跨域請求
    ]
    
    # 負責處理請求/回應的中間流程,包括安全性檢查、跨域處理、Session管理等
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.security.SecurityMiddleware',
        ...
    ]
    
    # 發送跨域請求來源設定
    CORS_ALLOW_ALL_ORIGINS = True
    
    # 主要URL配置檔位置
    ROOT_URLCONF = 'apps.urls'
    
    # DRF設定
    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 5,
    }
    
    # 資料庫設定
    DATABASES = {
        'default': {
            'ENGINE': 'mssql',
            'NAME': env('DB_NAME'),
            ...
        }
    }
    
    # 語言、時區設定
    LANGUAGE_CODE = 'en-us'
    TIME_ZONE = 'UTC'
    USE_TZ = True
    
  • 接著經由apps/urls.py,以進行url路由配置,以決定哪個網址會連線到哪個app,如設定admin/連線到後台管理介面,或者設定employee/連線到員工資料庫,參考如下:

    # apps/urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/employee/', include('employee.urls')),
    ]
    

我們可以看到,員工資料庫有配置到自己的網址,可以把它當作切分一個網址,供該資料庫使用,因此在Django專案中,會有一個對應的資料夾,如employee/,專門處理連線至此網址的操作。

因此,最先要了解的還是employee/urls.py,從url如何派發的路由設定,可最直接知道該如何進行API請求,如連線到employee/可查詢全部員工資料,而連線到employee/id/可取得單一員工的資料。

# employee/urls.py
router = DefaultRouter()

urlpatterns = [
    path('', EmployeeListCreateView.as_view(), name='employee-list-create'),
    path('<int:pk>/', EmployeeDetailView.as_view(), name='employee-detail'),

]

當送出API請求後,經urls派發,最先交給employee/views.py處理,當收到的是API請求時,會到資料庫去尋找符合的資料,並經由employee/serializers.py將資料庫格式,轉換為JSON格式,轉換過程中,並可預先決定是否及提供何種欄位資料,並回傳結果。

而員工資料庫的資料設定,可以參考employee/models.py,其中針對不同的資料欄位,設定要儲存的資料名稱及限制,有助於前端網頁開發者,快速了解資料庫結構,參考如下:

# employee/models.py
class Employee(models.Model):
    name = models.CharField(max_length=100, verbose_name="姓名")
    age = models.PositiveIntegerField(validators=[MinValueValidator(0)], verbose_name="年齡")
    phone = models.CharField(max_length=20, verbose_name="電話")

    IDENTITY_CHOICES = (
        ('FULL', '正職'),
        ('PART', '兼職'),
    )
    identity = models.CharField(
        max_length=4,
        choices=IDENTITY_CHOICES,
        default='FULL',
        verbose_name="身份別"
    )

    SALARY_TYPE_CHOICES = (
        ('MONTH', '月薪'),
        ('HOUR', '時薪'),
    )
    salary_type = models.CharField(
        max_length=5,
        choices=SALARY_TYPE_CHOICES,
        default='MONTH',
        verbose_name="薪資類型"
    )

    insert_date = models.DateField(auto_now_add=True, verbose_name="建立日期")
    update_date = models.DateField(auto_now=True, verbose_name="更新日期")

    def __str__(self):
        return f"{self.name} ({self.get_identity_display()})"

    class Meta:
        db_table = "Employee"
        verbose_name = "員工"
        verbose_name_plural = "員工"

前端發送請求至後端,乃至於回傳資料給前端,相關的流程圖,參考如下。此有助於前端開發者,初步了解後端運作方式,並對未來深入學習後端知識,提供一個入門的基礎。

[Browser/前端]
  │  HTTP/JSON
  ▼
[Web Server反向代理:Nginx/Apache]   ← 靜態檔案(static/)可直接由這層服務
  │  WSGI or ASGI
  ▼
[WSGI/ASGI Server: gunicorn/uWSGI/uvicorn/daphne]
  │  匯入apps/wsgi.py或apps/asgi.py
  ▼
[Django專案核心]
  ├─ settings.py  ← 全域設定(INSTALLED_APPS / MIDDLEWARE / DATABASES
  │                          / REST_FRAMEWORK / CORS / ALLOWED_HOSTS
  │                          / TIME_ZONE等)
  ├─ urls.py      ← 路由總表(/api/employee/轉給employee/urls.py)
  ├─ middleware   ← 請求/回應的中間處理(CORS、Security、Session、CSRF等)
  └─ apps/…       ← 主專案模組
        │
        └── [App: employee]
             ├─ urls.py          ← /api/employee/下各API
             ├─ views.py         ← 實作邏輯(接收參數、查詢資料、回傳JSON)
             ├─ serializers.py   ← 轉換器(Model ↔ JSON)
             └─ models.py        ← 資料表結構(ORM)
                    │
                    ▼
              [Django ORM] ↔ [SQL Server(DATABASES設定)]

上一篇
Day 25: Vue表單前端驗證及正則表達式(regular expression)
下一篇
Day 27: Docker編排檔(.yml)介紹及容器啟動
系列文
從零打造網頁系統:非資訊人也能完成的全端專題實作29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言