全棧開發(fā)進(jìn)階:Python后端(FastAPI/Flask)+ React/Vue前端集成完整教程
前言
大家好,我是第一程序員(名字大,人很菜)。作為一個(gè)非科班轉(zhuǎn)碼、正在學(xué)習(xí)Rust和Python的萌新,最近我開始學(xué)習(xí)Python與前端技術(shù)的集成。說實(shí)話,一開始我對全棧開發(fā)的概念還很模糊,但隨著學(xué)習(xí)的深入,我發(fā)現(xiàn)Python作為后端與前端框架的結(jié)合可以構(gòu)建出功能強(qiáng)大的全棧應(yīng)用。今天我想分享一下我對Python與前端集成的學(xué)習(xí)心得,希望能給同樣是非科班轉(zhuǎn)碼的朋友們一些參考。
全棧開發(fā)指同時(shí)掌握前端(用戶界面交互)和后端(服務(wù)器、數(shù)據(jù)庫、業(yè)務(wù)邏輯)的開發(fā)能力。Python憑借其簡潔語法、豐富的Web框架(Django、Flask、FastAPI)和強(qiáng)大的數(shù)據(jù)生態(tài),已成為全棧開發(fā)的熱門選擇之一。對于非科班轉(zhuǎn)碼者,從Python入手全棧,學(xué)習(xí)曲線相對平緩。
不要一次性學(xué)習(xí)所有框架,先選一個(gè)后端框架(推薦FastAPI或Flask)和一個(gè)前端框架(React或Vue)深入實(shí)踐,再做橫向拓展。
一、后端API設(shè)計(jì)
1.1 使用FastAPI創(chuàng)建RESTful API
FastAPI是一個(gè)現(xiàn)代化的Python Web框架,非常適合構(gòu)建RESTful API(一種基于HTTP協(xié)議、符合REST架構(gòu)風(fēng)格的接口設(shè)計(jì)規(guī)范)
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
app = FastAPI()
class Item(BaseModel):
id: int
name: str
price: float
is_offer: bool = None
items = []
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
@app.get("/items/{item_id}")
def read_item(item_id: int):
for item in items:
if item.id == item_id:
return item
return {"error": "Item not found"}
@app.post("/items/")
def create_item(item: Item):
items.append(item)
return item
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
for i, existing_item in enumerate(items):
if existing_item.id == item_id:
items[i] = item
return item
return {"error": "Item not found"}
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
for i, item in enumerate(items):
if item.id == item_id:
items.pop(i)
return {"message": "Item deleted"}
return {"error": "Item not found"}
1.2 使用Flask創(chuàng)建RESTful API
Flask是另一個(gè)流行的Python Web框架,也可以用于構(gòu)建RESTful API:
from flask import Flask, request, jsonify
app = Flask(__name__)
items = []
@app.route('/', methods=['GET'])
def read_root():
return jsonify({"message": "Hello, World!"})
@app.route('/items/<int:item_id>', methods=['GET'])
def read_item(item_id):
for item in items:
if item['id'] == item_id:
return jsonify(item)
return jsonify({"error": "Item not found"})
@app.route('/items/', methods=['POST'])
def create_item():
item = request.get_json()
items.append(item)
return jsonify(item)
@app.route('/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
item = request.get_json()
for i, existing_item in enumerate(items):
if existing_item['id'] == item_id:
items[i] = item
return jsonify(item)
return jsonify({"error": "Item not found"})
@app.route('/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
for i, item in enumerate(items):
if item['id'] == item_id:
items.pop(i)
return jsonify({"message": "Item deleted"})
return jsonify({"error": "Item not found"})
if __name__ == '__main__':
app.run(debug=True)
二、前端框架集成
2.1 與React集成
React是一個(gè)流行的前端框架,可以與Python后端API集成:
// App.js
import React, { useState, useEffect } from 'react';
function App() {
const [items, setItems] = useState([]);
const [newItem, setNewItem] = useState({ id: '', name: '', price: '', is_offer: false });
useEffect(() => {
fetch('http://localhost:8000/items/')
.then(response => response.json())
.then(data => setItems(data));
}, []);
const handleSubmit = (e) => {
e.preventDefault();
fetch('http://localhost:8000/items/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newItem),
})
.then(response => response.json())
.then(data => {
setItems([...items, data]);
setNewItem({ id: '', name: '', price: '', is_offer: false });
});
};
return (
<div>
<h1>Items</h1>
<ul>
{items.map(item => (
<li key={item.id}>
{item.name} - ${item.price}
</li>
))}
</ul>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="ID"
value={newItem.id}
onChange={(e) => setNewItem({...newItem, id: parseInt(e.target.value)})}
/>
<input
type="text"
placeholder="Name"
value={newItem.name}
onChange={(e) => setNewItem({...newItem, name: e.target.value})}
/>
<input
type="number"
placeholder="Price"
value={newItem.price}
onChange={(e) => setNewItem({...newItem, price: parseFloat(e.target.value)})}
/>
<button type="submit">Add Item</button>
</form>
</div>
);
}
export default App;
2.2 與Vue集成
Vue是另一個(gè)流行的前端框架,也可以與Python后端API集成:
<!-- App.vue -->
<template>
<div>
<h1>Items</h1>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }} - ${{ item.price }}
</li>
</ul>
<form @submit.prevent="handleSubmit">
<input
type="text"
placeholder="ID"
v-model.number="newItem.id"
/>
<input
type="text"
placeholder="Name"
v-model="newItem.name"
/>
<input
type="number"
placeholder="Price"
v-model.number="newItem.price"
/>
<button type="submit">Add Item</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
newItem: { id: '', name: '', price: '', is_offer: false }
};
},
mounted() {
this.fetchItems();
},
methods: {
fetchItems() {
fetch('http://localhost:8000/items/')
.then(response => response.json())
.then(data => {
this.items = data;
});
},
handleSubmit() {
fetch('http://localhost:8000/items/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(this.newItem),
})
.then(response => response.json())
.then(data => {
this.items.push(data);
this.newItem = { id: '', name: '', price: '', is_offer: false };
});
}
}
};
</script>
三、數(shù)據(jù)傳輸
3.1 JSON數(shù)據(jù)格式
JSON是前后端數(shù)據(jù)傳輸?shù)臉?biāo)準(zhǔn)格式:
# 后端返回JSON數(shù)據(jù)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
id: int
name: str
price: float
@app.get("/item", response_model=Item)
def get_item():
return {"id": 1, "name": "Item 1", "price": 10.99}
3.2 處理CORS
跨域資源共享(CORS)是前后端集成中常見的問題:
# FastAPI處理CORS
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# 配置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 在生產(chǎn)環(huán)境中應(yīng)該設(shè)置具體的域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
# Flask處理CORS
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # 允許所有跨域請求
@app.route('/')
def read_root():
return jsonify({"message": "Hello, World!"})
四、認(rèn)證與授權(quán)
4.1 JWT認(rèn)證
JSON Web Token(JWT)是一種常用的認(rèn)證方式:
# FastAPI中使用JWT
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from datetime import datetime, timedelta
from pydantic import BaseModel
app = FastAPI()
# 配置
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# 模擬用戶數(shù)據(jù)庫
fake_users_db = {
"alice": {
"username": "alice",
"full_name": "Alice Smith",
"email": "alice@example.com",
"hashed_password": "fakehashedsecret",
"disabled": False,
}
}
# 工具函數(shù)
def fake_hash_password(password: str):
return "fakehashed" + password
def verify_password(plain_password, hashed_password):
return hashed_password == fake_hash_password(plain_password)
def get_user(db, username: str):
if username in db:
user_dict = db[username]
return user_dict
def create_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# 依賴
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
user = get_user(fake_users_db, username=username)
if user is None:
raise credentials_exception
return user
# 路由
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = get_user(fake_users_db, form_data.username)
if not user:
raise HTTPException(status_code=400, detail="Incorrect username or password")
if not verify_password(form_data.password, user["hashed_password"]):
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user["username"]}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/users/me")
async def read_users_me(current_user: dict = Depends(get_current_user)):
return current_user
五、部署
5.1 部署后端
使用Docker部署Python后端:
# Dockerfile FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
5.2 部署前端
使用Vercel、Netlify等平臺(tái)部署前端:
- Vercel:適合部署React、Next.js應(yīng)用
- Netlify:適合部署Vue、React應(yīng)用
- GitHub Pages:適合部署靜態(tài)網(wǎng)站
5.3 完整部署
使用Docker Compose部署前后端:
# docker-compose.yml
version: '3'
services:
backend:
build: ./backend
ports:
- "8000:8000"
frontend:
build: ./frontend
ports:
- "3000:3000"
depends_on:
- backend
六、Python與Rust的對比
作為一個(gè)同時(shí)學(xué)習(xí)Python和Rust的轉(zhuǎn)碼者,我發(fā)現(xiàn)對比學(xué)習(xí)是一種很好的方法:
6.1 前端集成對比
- Python:生態(tài)豐富,有FastAPI、Flask等框架
- Rust:有Actix-web、Rocket等框架
- 開發(fā)效率:Python開發(fā)效率高,Rust開發(fā)效率相對較低
- 性能:Rust性能優(yōu)異,Python性能相對較低
6.2 學(xué)習(xí)心得
- Python的優(yōu)勢:開發(fā)效率高,生態(tài)豐富
- Rust的優(yōu)勢:性能優(yōu)異,內(nèi)存安全
- 相互借鑒:從Python學(xué)習(xí)快速開發(fā),從Rust學(xué)習(xí)性能優(yōu)化
七、實(shí)踐項(xiàng)目推薦
7.1 全棧項(xiàng)目
- 博客系統(tǒng):使用Python作為后端,React/Vue作為前端
- 電商系統(tǒng):使用Python作為后端,React/Vue作為前端
- 社交應(yīng)用:使用Python作為后端,React/Vue作為前端
- 數(shù)據(jù)分析平臺(tái):使用Python作為后端,React/Vue作為前端
八、學(xué)習(xí)方法和技巧
8.1 學(xué)習(xí)方法
- 循序漸進(jìn):先學(xué)習(xí)后端API開發(fā),再學(xué)習(xí)前端框架
- 項(xiàng)目實(shí)踐:通過實(shí)際項(xiàng)目來鞏固知識(shí)
- 文檔閱讀:仔細(xì)閱讀框架的官方文檔
- 社區(qū)交流:加入社區(qū),向他人學(xué)習(xí)
8.2 常見問題和解決方法
- CORS問題:配置CORS中間件
- 認(rèn)證問題:使用JWT等認(rèn)證方式
- 部署問題:使用Docker等容器化技術(shù)
- 性能問題:優(yōu)化API設(shè)計(jì),使用緩存
九、總結(jié)
Python與前端技術(shù)的集成可以構(gòu)建出功能強(qiáng)大的全棧應(yīng)用。作為一個(gè)非科班轉(zhuǎn)碼者,我深刻體會(huì)到全棧開發(fā)的重要性。
到此這篇關(guān)于全棧開發(fā)進(jìn)階:Python后端(FastAPI/Flask)+ React/Vue前端集成完整教程的文章就介紹到這了,更多相關(guān)Python前端框架全棧開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python Flask結(jié)合前端Fetch搞定表單提交和頁面刷新
- python如何與前端交互舉例詳解
- python傳到前端的數(shù)據(jù),雙引號(hào)被轉(zhuǎn)義的問題
- python 實(shí)現(xiàn)Flask中返回圖片流給前端展示
- python將圖片轉(zhuǎn)base64,實(shí)現(xiàn)前端顯示
- python實(shí)現(xiàn)通過flask和前端進(jìn)行數(shù)據(jù)收發(fā)
- Flask框架實(shí)現(xiàn)的前端RSA加密與后端Python解密功能詳解
- python后端接收前端回傳的文件方法
- 為Python的web框架編寫前端模版的教程
相關(guān)文章
解決import tensorflow as tf 出錯(cuò)的原因
這篇文章主要介紹了解決import tensorflow as tf 出錯(cuò)的原因,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Python實(shí)現(xiàn)字典排序、按照list中字典的某個(gè)key排序的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)字典排序、按照list中字典的某個(gè)key排序的方法,涉及Python字典與列表排序相關(guān)操作技巧,需要的朋友可以參考下2018-12-12
python 實(shí)現(xiàn)交換兩個(gè)列表元素的位置示例
今天小編就為大家分享一篇python 實(shí)現(xiàn)交換兩個(gè)列表元素的位置示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
Python+OpenCV 實(shí)現(xiàn)圖片無損旋轉(zhuǎn)90°且無黑邊
今天小編就為大家分享一篇Python+OpenCV 實(shí)現(xiàn)圖片無損旋轉(zhuǎn)90°且無黑邊,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
使用Python處理Excel文件并將數(shù)據(jù)存儲(chǔ)到PostgreSQL的方法
在日常工作中,我們經(jīng)常會(huì)遇到需要處理大量文件并將數(shù)據(jù)存儲(chǔ)至數(shù)據(jù)庫或整合到一個(gè)文件的需求,本文將向大家展示如何使用Python處理Excel文件并將數(shù)據(jù)存儲(chǔ)到PostgreSQL數(shù)據(jù)庫中,需要的朋友可以參考下2024-01-01
Python中常見路徑算法的原理與實(shí)現(xiàn)詳解
在計(jì)算機(jī)科學(xué)中,路徑算法是解決許多實(shí)際問題的核心工具,本文介紹了Python中三種常見的路徑算法及其實(shí)現(xiàn),幫助讀者快速上手并理解這些算法的原理和應(yīng)用2026-04-04

