6.1 KiB
6.1 KiB
第四章 架构设计 - 技术栈选型
4.1 后端技术栈
Django 6.0.3
选型理由:
- 成熟稳定的 Python Web 框架,社区活跃,文档完善
- 内置 ORM、Admin 后台、表单验证等开箱即用的功能
- 完善的安全机制(CSRF、XSS、SQL注入防护)
- 灵活的中间件和信号机制,便于扩展
关键配置(application/settings.py):
# 数据库配置
DATABASES = {
"default": {
"ENGINE": env.DATABASE_ENGINE, # django.db.backends.mysql
"NAME": env.DATABASE_NAME,
"USER": env.DATABASE_USER,
"PASSWORD": env.DATABASE_PASSWORD,
"HOST": env.DATABASE_HOST,
"PORT": env.DATABASE_PORT,
}
}
# 缓存配置(Redis)
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": f"redis://{env.REDIS_HOST}:{env.REDIS_PORT}/{env.REDIS_DB}",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
},
"KEY_PREFIX": "djangoadmin",
}
}
MySQL 8.0
选型理由:
- 生产级关系型数据库,性能稳定可靠
- 支持事务、外键、索引等企业级特性
- 与 Django ORM 深度集成,驱动成熟
- 社区版免费,降低项目成本
配置说明(config/env.py):
DATABASE_ENGINE = os.getenv('DATABASE_ENGINE', "django.db.backends.mysql")
DATABASE_NAME = os.getenv('DATABASE_NAME', 'djangoadmin.django.antdvue')
DATABASE_HOST = os.getenv('DATABASE_HOST', "127.0.0.1")
DATABASE_PORT = os.getenv('DATABASE_PORT', 3306)
DATABASE_USER = os.getenv('DATABASE_USER', 'root')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD', 'root')
DATABASE_PREFIX = os.getenv('DATABASE_PREFIX', "django_")
Redis
选型理由:
- 高性能内存数据库,读写延迟极低
- 支持多种数据结构(String、Hash、List、Set)
- 用于缓存、会话存储、Token 黑名单等场景
- 支持过期时间设置,适合临时数据存储
应用场景:
| 场景 | 数据结构 | Key格式 | 说明 |
|---|---|---|---|
| Token黑名单 | String | token:blacklist:<fingerprint> |
存储已注销的JWT Token |
| IP地理位置缓存 | String | ip:location:<ip> |
缓存IP查询结果 |
| 验证码存储 | String | captcha:<key> |
存储图形验证码 |
4.2 认证技术
JWT (JSON Web Token)
选型理由:
- 无状态认证,服务端无需存储会话信息
- 支持分布式部署,无 Session 共享问题
- Token 自包含用户信息,减少数据库查询
- 标准化协议,前后端通用
实现细节(utils/jwt.py):
# JWT配置
JWT_SALT = os.environ.get('JWT_SALT', None) # 密钥,优先从环境变量读取
JWT_ALGORITHM = 'HS256' # 签名算法
DEFAULT_TIMEOUT_MINUTES = 20 # 默认过期时间(分钟)
def create_token(payload, timeout=None):
"""生成JWT令牌"""
payload_copy = payload.copy()
payload_copy['exp'] = current_time + datetime.timedelta(minutes=timeout)
payload_copy['iat'] = current_time
token = jwt.encode(payload=payload_copy, key=JWT_SALT, algorithm=JWT_ALGORITHM)
return token
def parse_payload(token):
"""解析验证JWT令牌"""
verified_payload = jwt.decode(token, JWT_SALT, algorithms=[JWT_ALGORITHM])
return verified_payload
Token 黑名单机制:
- 退出登录时将 Token 加入 Redis 黑名单
- 黑名单条目的 TTL 与 Token 剩余有效期一致
- Token 自然过期后黑名单条目自动清除
- 使用 SHA256 指纹避免存储完整 Token
4.3 前端技术栈
Vue3 + TypeScript
选型理由:
- 响应式框架,开发体验优秀
- Composition API 提供更好的代码组织方式
- TypeScript 提供类型安全,减少运行时错误
- 生态成熟,社区活跃
Ant Design Vue
选型理由:
- 基于 Vue3 的企业级 UI 组件库
- 组件丰富,覆盖表单、表格、弹窗等常见场景
- 文档完善,中文社区支持好
- 与 Vue3 深度集成
Vite
选型理由:
- 下一代前端构建工具,启动速度快
- 原生 ESM 支持,开发体验好
- 热更新速度快,提升开发效率
- 配置简洁,易于上手
开发代理配置(ui/.env.development):
VITE_PROXY = [["/api", "http://127.0.0.1:8000"]]
Pinia
选型理由:
- Vue3 官方推荐的状态管理方案
- 相比 Vuex 更简洁,支持 TypeScript
- 模块化设计,便于代码组织
- 支持 SSR,扩展性强
4.4 代码生成技术
Jinja2
选型理由:
- Python 生态成熟的模板引擎
- 语法简洁,学习成本低
- 支持模板继承和宏定义
- 与 Django 模板语法不冲突
模板目录(public/templates/):
public/templates/
+-- models.py.tpl # 模型模板
+-- forms.py.tpl # 表单模板
+-- services.py.tpl # 服务模板
+-- views.py.tpl # 视图模板
+-- urls.py.tpl # 路由模板
+-- apps.py.tpl # 应用配置模板
+-- admin.py.tpl # Admin注册模板
+-- ui/
+-- index.vue.tpl # 列表页模板
+-- edit.vue.tpl # 编辑页模板
+-- detail.vue.tpl # 详情页模板
+-- api.ts.tpl # API模块模板
4.5 依赖版本
后端依赖(requirements.txt)
Django==6.0.3
djangorestframework
django-redis
django-cors-headers
django-simple-captcha
PyJWT
mysqlclient
redis
jinja2
前端依赖(package.json)
{
"dependencies": {
"vue": "^3.x",
"ant-design-vue": "^3.x",
"pinia": "^2.x",
"vue-router": "^4.x",
"axios": "^1.x"
},
"devDependencies": {
"vite": "^5.x",
"typescript": "^5.x",
"vue-tsc": "^2.x"
}
}
4.6 版本兼容性
| 组件 | 最低版本 | 推荐版本 | 说明 |
|---|---|---|---|
| Python | 3.12 | 3.12+ | 推荐使用 Python 3.12 |
| MySQL | 8.0 | 8.0+ | 需要支持 JSON 字段 |
| Redis | 6.0 | 7.0+ | 需要支持 Stream 等特性 |
| Node.js | 18.0 | 20+ | Vite 5 要求 Node 18+ |
| pnpm | 12.0 | 12+ | 包管理器 |