260 lines
6.7 KiB
Markdown
260 lines
6.7 KiB
Markdown
# 常见问题与排错
|
||
|
||
本章汇总模块开发过程中的常见问题和解决方案。
|
||
|
||
## 后端问题
|
||
|
||
### Q1: 启动报错 `Table 'xxx.django_example' doesn't exist`
|
||
|
||
**原因**:模型定义后未执行数据库迁移。
|
||
|
||
**解决**:
|
||
|
||
```bash
|
||
# 生成迁移文件
|
||
python manage.py makemigrations example
|
||
|
||
# 执行迁移
|
||
python manage.py migrate
|
||
```
|
||
|
||
### Q2: 接口返回 `{"code": 1, "msg": "暂无操作权限"}`
|
||
|
||
**原因**:权限节点未配置或未分配给当前用户角色。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认菜单管理中已添加权限节点,权限标识与代码中 `permission_required` 完全一致
|
||
2. 确认权限节点已分配给当前用户的角色
|
||
3. 使用 admin 账号(ID=1)测试,admin 自动跳过权限校验
|
||
|
||
```python
|
||
# 权限标识必须完全一致
|
||
permission_required = ("sys:example:page",) # 代码中
|
||
sys:example:page # 菜单管理中
|
||
```
|
||
|
||
### Q3: 接口返回 `{"code": 1, "msg": "演示环境,暂无操作权限"}`
|
||
|
||
**原因**:`.env` 中设置了 `DJANGO_DEMO=True`。
|
||
|
||
**解决**:将 `.env` 中的 `DJANGO_DEMO` 设为 `False`:
|
||
|
||
```bash
|
||
DJANGO_DEMO=False
|
||
```
|
||
|
||
### Q4: 分页查询返回空数据
|
||
|
||
**原因**:分页参数名不匹配或字段配置错误。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 前端传参名应为 `pageNo` 和 `pageSize`(驼峰)
|
||
2. 检查数据库中是否有数据(`is_delete=0` 的记录)
|
||
3. 检查筛选条件是否正确
|
||
|
||
```python
|
||
# 正确的参数获取方式
|
||
page_no = int(request.GET.get('pageNo', 1))
|
||
page_size = int(request.GET.get('pageSize', PAGE_SIZE))
|
||
```
|
||
|
||
### Q5: 表单验证错误信息不显示中文
|
||
|
||
**原因**:`error_messages` 配置不完整。
|
||
|
||
**解决**:确保每个验证规则都配置了中文错误提示:
|
||
|
||
```python
|
||
name = forms.CharField(
|
||
required=True,
|
||
max_length=100,
|
||
error_messages={
|
||
'required': '案例名称不能为空',
|
||
'max_length': '案例名称长度不得超过100个字符',
|
||
}
|
||
)
|
||
```
|
||
|
||
### Q6: 删除操作不生效
|
||
|
||
**原因**:删除使用逻辑删除,查询时需要加 `is_delete=False` 条件。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认删除函数使用 `update(is_delete=True)` 而非 `delete()`
|
||
2. 确认所有查询都加了 `is_delete=False` 条件
|
||
3. 检查数据库中 `is_delete` 字段的值
|
||
|
||
```python
|
||
# 正确的逻辑删除
|
||
Example.objects.filter(id__in=id_list, is_delete=False).update(is_delete=True)
|
||
|
||
# 正确的查询
|
||
Example.objects.filter(is_delete=False)
|
||
```
|
||
|
||
### Q7: 文件上传后路径不正确
|
||
|
||
**原因**:`save_file()` 函数使用不正确。
|
||
|
||
**解决**:确保传入的是完整的文件 URL,并指定正确的目录名:
|
||
|
||
```python
|
||
# 正确用法
|
||
avatar = save_file(avatar_url, "example")
|
||
|
||
# avatar_url 应该是类似 http://xxx/uploads/temp/xxx.jpg 的完整URL
|
||
```
|
||
|
||
### Q8: `get_username(request)` 返回空字符串
|
||
|
||
**原因**:JWT Token 中没有 `realname` 字段,或 Token 已过期。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认请求头包含 `Authorization: Bearer <token>`
|
||
2. 确认 Token 未过期
|
||
3. 确认用户信息中包含 `realname` 字段
|
||
|
||
## 前端问题
|
||
|
||
### Q9: 页面白屏,控制台报 `Failed to fetch dynamically imported module`
|
||
|
||
**原因**:路由组件路径配置错误。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认后端菜单的 `component` 字段值正确(如 `tool/example/index`)
|
||
2. 确认前端文件路径与 `component` 对应(`ui/src/views/tool/example/index.vue`)
|
||
3. 检查文件名大小写是否匹配
|
||
|
||
### Q10: 搜索功能不生效
|
||
|
||
**原因**:搜索表单的 `submit` 事件未正确绑定。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认 `BasicForm` 绑定了 `@submit="handleSubmit"` 事件
|
||
2. 确认 `handleSubmit` 中更新了 `formParams` 并调用了 `reloadTable()`
|
||
3. 确认后端 `_apply_filters` 函数正确处理了筛选参数
|
||
|
||
### Q11: 编辑弹窗不回填数据
|
||
|
||
**原因**:`setFormData` 未正确调用或 API 返回数据格式不对。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认 `props.id` 不为 0(编辑模式)
|
||
2. 确认 `getExampleDetail` API 返回了正确的数据
|
||
3. 确认 `formData` 的字段名与 API 返回的字段名一致
|
||
|
||
### Q12: 操作按钮不显示
|
||
|
||
**原因**:`v-perm` 权限标识与后端不一致。
|
||
|
||
**排查步骤**:
|
||
|
||
1. 确认 `v-perm` 中的权限字符串与后端 `permission_required` 完全一致
|
||
2. 确认当前用户拥有对应权限
|
||
3. 检查 `TableAction` 中的 `auth` 字段是否正确
|
||
|
||
```vue
|
||
<!-- 权限标识必须与后端一致 -->
|
||
<n-button v-perm="['sys:example:add']">添加案例</n-button>
|
||
```
|
||
|
||
### Q13: 表格数据不刷新
|
||
|
||
**原因**:操作成功后未调用 `reloadTable()`。
|
||
|
||
**解决**:在弹窗的 `success` 事件中刷新表格:
|
||
|
||
```vue
|
||
<editDialog @success="reloadTable('noRefresh')" />
|
||
```
|
||
|
||
## 通用问题
|
||
|
||
### Q14: 接口返回 401 Unauthorized
|
||
|
||
**原因**:JWT Token 过期或未携带。
|
||
|
||
**解决**:
|
||
|
||
1. 确认请求头包含 `Authorization: Bearer <token>`
|
||
2. Token 过期后需重新登录
|
||
3. 前端 `http` 自动处理 Token 注入,检查是否正确引入
|
||
|
||
### Q15: 数据库字段中文乱码
|
||
|
||
**原因**:数据库或表的字符集不是 UTF-8。
|
||
|
||
**解决**:确保 MySQL 数据库和表使用 `utf8mb4` 字符集:
|
||
|
||
```sql
|
||
ALTER DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||
```
|
||
|
||
### Q16: `DJANGO_DEMO` 环境变量不生效
|
||
|
||
**原因**:`.env` 文件修改后未重启服务。
|
||
|
||
**解决**:修改 `.env` 后必须重启 Django 服务:
|
||
|
||
```bash
|
||
# 停止服务后重新启动
|
||
python manage.py runserver
|
||
```
|
||
|
||
## 开发调试技巧
|
||
|
||
### 查看 SQL 日志
|
||
|
||
在 `settings.py` 中开启 SQL 调试:
|
||
|
||
```python
|
||
LOGGING = {
|
||
'handlers': {
|
||
'console': {
|
||
'class': 'logging.StreamHandler',
|
||
},
|
||
},
|
||
'loggers': {
|
||
'django.db.backends': {
|
||
'level': 'DEBUG',
|
||
'handlers': ['console'],
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
### 使用 Django Admin 调试
|
||
|
||
访问 `http://127.0.0.1:8000/admin/`,可以直接在浏览器中查看和编辑数据库数据。
|
||
|
||
### 检查权限配置
|
||
|
||
如果不确定权限是否配置正确,可以用 admin 账号测试。admin(ID=1)自动跳过所有权限校验。
|
||
|
||
### 测试 API 接口
|
||
|
||
使用 curl 或 Postman 测试 API 接口:
|
||
|
||
```bash
|
||
# 登录获取 Token
|
||
curl -X POST http://127.0.0.1:8000/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username": "admin", "password": "123456"}'
|
||
|
||
# 使用 Token 访问接口
|
||
curl -X GET http://127.0.0.1:8000/example/page?pageNo=1&pageSize=10 \
|
||
-H "Authorization: Bearer <token>"
|
||
```
|
||
|
||
## 总结
|
||
|
||
模块开发常见问题主要集中在:数据库迁移未执行、权限节点未配置、软删除过滤缺失、分页参数命名不一致、前端组件路径配置错误等。遇到问题时优先检查后端日志和网络请求,确认接口入参和返回值是否符合预期。
|