Django 和 Vue3 前后端分離開發筆記
1. Django Ninja API
Django Ninja 是一個用于使用 Django 和 Python 3.6+ 類型提示構建 API 的網絡框架。它具有以下主要特點:
- 簡單易懂:設計為易于使用和符合直覺,適合快速上手。
- 快速執行:多虧了 Pydantic 和異步支持,具有非常高的性能。
- 快速編程:類型提示和自動文檔生成讓開發者只需關注業務邏輯。
- 基于標準:基于 OpenAPI(以前稱為 Swagger)和 JSON 模式。
- 對 Django 友好:與 Django 核心和 ORM 有良好的集成。
- 可用于生產:被多家公司用于實際項目,穩定可靠。
創建和使用 NinjaAPI
-
安裝 Django Ninja:
pip install django-ninja
-
創建 Django 項目(如果還沒有):
django-admin startproject apidemo cd apidemo
-
在
urls.py
中配置 API:# apidemo/urls.py from django.contrib import admin from django.urls import path from ninja import NinjaAPIapi = NinjaAPI()@api.get("/add") def add(request, a: int, b: int):return {"result": a + b}urlpatterns = [path("admin/", admin.site.urls),path("api/", api.urls), ]
-
運行項目:
python manage.py runserver
-
訪問 API:
打開瀏覽器,訪問http://127.0.0.1:8000/api/add?a=1&b=2
,你將看到 JSON 響應為:{"result": 3}
-
交互式 API 文檔:
訪問http://127.0.0.1:8000/api/docs
,你將看到自動的、交互式 API 文檔(由 OpenAPI / Swagger UI 或 Redoc 提供)。
NinjaAPI 的主要參數
- title:API 的標題。
- version:API 的版本。
- description:API 的描述。
- openapi_url:OpenAPI 規范的相對 URL。
- docs_url:API 文檔的相對 URL。
- servers:目標主機列表,用于 OpenAPI 規范。
- csrf:是否要求 CSRF 令牌(已棄用,現在由
auth
處理)。 - auth:認證類。
- renderer:默認響應渲染器。
- parser:默認請求解析器。
- openapi_extra:OpenAPI 規范的額外屬性。
示例
以下是一個更復雜的示例,展示了如何使用 NinjaAPI 創建一個帶有輸入和輸出模型的 API:
# apidemo/api.py
from ninja import NinjaAPI, Schema
from ninja import UploadedFile, File
from django.core.files.storage import FileSystemStorage
from django.shortcuts import get_object_or_404
from .models import Employee, Departmentapi = NinjaAPI()class EmployeeIn(Schema):first_name: strlast_name: strdepartment_id: int = Nonebirthdate: date = Noneclass EmployeeOut(Schema):id: intfirst_name: strlast_name: strdepartment_id: int = Nonebirthdate: date = None@api.post("/employees")
def create_employee(request, payload: EmployeeIn, cv: UploadedFile = File(...)):fs = FileSystemStorage()filename = fs.save(cv.name, cv)payload_dict = payload.dict()payload_dict['cv'] = filenameemployee = Employee.objects.create(**payload_dict)return {"id": employee.id}@api.get("/employees/{employee_id}")
def get_employee(request, employee_id: int):employee = get_object_or_404(Employee, id=employee_id)return EmployeeOut.from_orm(employee)
在這個示例中,我們定義了兩個模型 EmployeeIn
和 EmployeeOut
,分別用于輸入和輸出。我們還創建了兩個 API 端點:一個用于創建員工,另一個用于獲取員工信息。
在 urls.py
中使用 api.py
:
# apidemo/urls.py
from django.contrib import admin
from django.urls import path
from .api import apiurlpatterns = [path("admin/", admin.site.urls),path("api/", api.urls),
]
2. 跨域請求問題
從你提供的信息來看,你遇到了一個常見的跨源資源共享(CORS)問題。這個錯誤信息表明,當你從 http://localhost:5173
發起請求到 http://127.0.0.1:8000/api/test/
時,服務器沒有返回 Access-Control-Allow-Origin
頭,導致瀏覽器阻止了這次請求。
解決 CORS 問題的方法
1. 在服務器端設置 CORS 頭
最根本的解決方法是在服務器端設置 Access-Control-Allow-Origin
頭。
手動設置
from django.http import HttpResponsedef my_view(request):# 創建一個HttpResponse對象response = HttpResponse("這是我的響應內容")# 手動設置CORS頭部response['Access-Control-Allow-Origin'] = '*'return response
如果你使用的是 Django,可以安裝 django-cors-headers
庫來處理 CORS 問題。
-
安裝
django-cors-headers
:pip install django-cors-headers
-
在
settings.py
中配置:# apidemo/settings.pyINSTALLED_APPS = [...'corsheaders',... ]MIDDLEWARE = [...'corsheaders.middleware.CorsMiddleware','django.middleware.common.CommonMiddleware',... ]CORS_ALLOWED_ORIGINS = ["http://localhost:5173", ]
-
確保
CORS_ALLOWED_ORIGINS
包含你的前端開發服務器的 URL。
2. 使用代理
如果你無法修改服務器端的設置,可以在開發環境中使用代理來繞過 CORS 限制。Vite 提供了代理配置選項,可以在 vite.config.js
中設置。
-
創建或修改
vite.config.js
:// vite.config.js import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue';export default defineConfig({plugins: [vue()],server: {proxy: {'/api': {target: 'http://127.0.0.1:8000', changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}} });
-
修改請求 URL:
在前端代碼中,將請求 URL 從http://127.0.0.1:8000/api/test/
改為/api/test/
。// src/components/Person.vue fetch('/api/test/').then(response => {if (!response.ok) {throw new Error('Network response was not ok');}return response.json();}).then(data => {console.log(data);}).catch(error => {console.error('There was a problem with the fetch operation:', error);});
檢查和重試
-
檢查 URL 的合法性:
- 確保
http://127.0.0.1:8000/api/test/
是正確的,并且服務器已經啟動。 - 嘗試在瀏覽器中直接訪問該 URL,看是否能返回預期的結果。
- 確保
-
重試請求:
- 有時候網絡問題可能導致請求失敗,可以嘗試重新發送請求。
-
檢查網絡連接:
- 確保你的開發環境的網絡連接正常,沒有防火墻或代理服務器阻止請求。
總結
CORS 問題通常是由于服務器端沒有正確設置 Access-Control-Allow-Origin
頭導致的。你可以通過在服務器端設置 CORS 頭或在開發環境中使用代理來解決這個問題。如果問題仍然存在,建議檢查 URL 的合法性和網絡連接,適當重試請求。
Vue3 前端項目設置
1. 創建 Vue3 項目
你可以使用 Vue CLI 或 Vite 來創建 Vue3 項目。這里以 Vite 為例:
npm create vite@latest frontend --template vue
cd frontend
npm install
npm install axios
2. 配置 main.js
確保在 main.js
中引入 Vue 和 Axios:
// frontend/src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'const app = createApp(App)
app.config.globalProperties.$axios = axios
app.mount('#app')
3. 創建組件
創建一個簡單的組件來測試 API 請求:
<!-- frontend/src/components/Person.vue -->
<template><div><button @click="sendRequest">發送請求</button><hr><p>{{ response }}</p></div>
</template><script setup>
import { ref } from 'vue';
import axios from 'axios';const response = ref(null);async function sendRequest() {try {const res = await axios.get('/api/test/');response.value = res.data;} catch (error) {console.error('請求失敗:', error);}
}
</script><style scoped>
button {padding: 10px 20px;margin-bottom: 10px;
}
</style>
4. 運行 Vue3 項目
npm run dev
確保你的 Vue3 項目運行在 http://localhost:5173
,并且通過 Vite 配置的代理正確地將請求發送到 Django 后端。
數據庫模型示例
為了完整演示,這里提供一個簡單的數據庫模型示例:
# apidemo/models.py
from django.db import modelsclass Department(models.Model):name = models.CharField(max_length=100)def __str__(self):return self.nameclass Employee(models.Model):first_name = models.CharField(max_length=50)last_name = models.CharField(max_length=50)department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)birthdate = models.DateField(null=True, blank=True)cv = models.FileField(upload_to='cvs/', null=True, blank=True)def __str__(self):return f"{self.first_name} {self.last_name}"
5. 遷移數據庫
python manage.py makemigrations
python manage.py migrate
測試和調試
-
確保后端和前端都在運行:
- 后端:
http://127.0.0.1:8000
- 前端:
http://localhost:5173
- 后端:
-
檢查瀏覽器控制臺:
- 查看是否有任何錯誤信息。
- 確認請求是否成功,并且返回的數據是否正確。
-
使用 Postman 或瀏覽器開發者工具:
- 使用 Postman 測試 API 端點。
- 使用瀏覽器開發者工具查看網絡請求和響應。