在第27天,我們將進一步完善專案,對之前的功能進行調整、擴展,並優化程式碼以提升應用的效能與可維護性。本階段不僅是功能的完善,還涉及到如何撰寫更具結構性與高效的程式碼。
在前一階段的專案開發中,我們已經實作了基本的核心功能,接下來我們將加入一些附加功能,使專案更具實用性與完整性。
在多用戶系統中,不同的用戶需要擁有不同的權限,比如普通用戶與管理員的區分。我們可以透過設定用戶角色來控制哪些功能對應哪些角色開放。
新增角色模型
在數據庫中設置不同的用戶角色,並為每個用戶分配角色:
class Role(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
users = db.relationship('User', backref='role')
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
權限控制裝飾器
使用 Flask 的裝飾器來設置權限檢查功能,僅允許特定角色的用戶訪問特定路由:
from functools import wraps
from flask import redirect, url_for
def role_required(role_name):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if current_user.role.name != role_name:
return redirect(url_for('no_permission'))
return f(*args, **kwargs)
return decorated_function
return decorator
為了讓前端或其他應用能夠與我們的後端系統互動,我們可以新增 RESTful API 來提供數據訪問服務。這樣的 API 可以用於移動應用、前端 AJAX 請求,或是第三方整合。
建立 API 路由
使用 Flask 來設置 API 路由,並返回 JSON 格式的數據:
from flask import jsonify
@app.route('/api/users', methods=['GET'])
def get_users():
users = User.query.all()
return jsonify([user.to_dict() for user in users])
@app.route('/api/user/<int:id>', methods=['GET'])
def get_user(id):
user = User.query.get_or_404(id)
return jsonify(user.to_dict())
文件上傳功能可以進一步擴展,支持多文件上傳、文件預覽、以及對已上傳文件的管理。
多文件上傳與處理
使用 HTML 的 multiple
屬性來允許一次上傳多個文件,並在後端進行處理:
@app.route('/upload', methods=['POST'])
def upload_files():
if 'files[]' not in request.files:
return 'No file part'
files = request.files.getlist('files[]')
for file in files:
# 處理每個文件
file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
return 'Files uploaded successfully'
專案的第二階段重點不僅是功能上的擴展,更要注重程式碼的優化,提升應用的效能和可維護性。
在專案中,常常會遇到相似的程式碼片段。透過撰寫公共函數或使用設計模式,我們可以減少重複代碼,提升程式碼的可讀性與可維護性。
抽取公共函數
例如,對於多次使用的數據處理邏輯,可以將其封裝到單一的函數中,方便重用:
def save_file(file):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return filename
如果專案涉及到大量的數據處理或文件操作,則需要優化效能,減少不必要的資源消耗。
使用數據庫索引
對於頻繁查詢的數據表,可以考慮添加索引來加快查詢速度:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), index=True)
批量操作數據
遇到需要處理大量數據的情況時,優化資料庫的批量插入或更新操作,避免逐條處理:
db.session.bulk_insert_mappings(User, user_data_list)
使用 ORM(如 SQLAlchemy)時,應優化查詢以減少不必要的數據庫連接與操作次數。應用"懶載入"技術來延遲數據加載,避免查詢冗餘。
使用懶載入
將模型中的關聯設置為延遲加載,當真正需要時才進行查詢:
users = User.query.options(db.lazyload(User.role)).all()
在專案的後期階段,為了確保每次功能修改不會引入新的問題,我們可以設置自動化測試流程,並使用持續整合(CI)工具來監控測試情況。
撰寫更完整的單元測試
增加更多的測試覆蓋率,確保每個功能模組都有相應的測試用例:
def test_user_creation(self):
user = User(username='testuser', password='testpassword')
db.session.add(user)
db.session.commit()
self.assertEqual(user.username, 'testuser')
引入持續整合工具
使用工具如 GitHub Actions 或 Jenkins,自動化地運行測試並生成報告,確保每次提交的代碼都通過測試。
為了提高專案的可維護性與可擴展性,我們可以對專案進行重構,將代碼進一步模組化。
將專案中的不同功能拆分為模組,這樣能使程式碼結構更加清晰,方便日後的功能擴展與維護。
my_project/
├── app/
│ ├── auth/
│ ├── data/
│ ├── templates/
│ └── static/
使用 Flask 的藍圖(Blueprint)來劃分不同的功能模塊,如用戶管理模塊、數據處理模塊等:
from flask import Blueprint
auth = Blueprint('auth', __name__)
@auth.route('/login')
def login():
return 'Login Page'
經過前兩天的專案實作,我們已經完成了一個具有多功能的應用程序。但專案的開發永遠沒有止境,還有許多擴展與優化的可能性。接下來的步驟可以包括: