Django+React项目访问详情页遇500错误及路由跳转至undefined问题
Django+React项目项目详情页访问问题排查与修复
问题现象
- 项目列表页
http://localhost:3000/projects/可正常访问 - 点击列表页链接跳转至项目详情页时,路径变为
http://localhost:3000/projects/undefined - 控制台报错:
GET http://localhost:8000/api/projects/undefined/ 500 (Internal Server Error) - Django终端报错:
base.models.Project.DoesNotExist: Project matching query does not exist.
问题根源
前端问题
- React路由定义中,详情页参数用
:id,但实际项目用slug,命名不匹配 - 手动拆分URL获取参数的方式不可靠,易受URL末尾斜杠影响导致拿到
undefined fetchproject函数参数传递错误:用了解构赋值但调用时传普通字符串,导致slug变量未正确接收
后端问题
- URL路由中
<slug:slug>的HTML实体编码错误(原代码写的是<slug:slug>) projectview视图直接用get()查询,未处理项目不存在的情况,直接抛出500错误
修复步骤
前端修复(React部分)
1. 修正App.js路由参数名
把详情页路由的:id改成:slug,和后端参数对应:
// App.js <Route path="/projects/:slug" element={<Project />} />
2. 用useParams正确获取路由参数
替换手动拆分URL的方式,改用react-router-dom提供的useParams:
// project.js import { React, useState, useEffect } from 'react'; import axios from 'axios'; import { Row, Col, Image, ListGroup } from 'react-bootstrap' import { useParams } from 'react-router-dom'; // 新增导入 import './index.css' import './bootstrap.min.css' function Project() { const [project, setProject] = useState({}); // 初始值用空对象更合理 const { slug } = useParams(); // 获取路由参数 useEffect(() => { const fetchProject = async () => { try { const res = await axios.get(`http://localhost:8000/api/projects/${slug}/`); // 匹配后端URL末尾的斜杠 setProject(res.data); } catch (err) { console.error('获取项目详情失败:', err); } }; if (slug) { // 确保slug存在再发起请求 fetchProject(); } }, [slug]); // 依赖项添加slug,参数变化时重新请求 return ( <div> <Row className="my-1 p-4"> <Col xs={3} sm={2} md={2} lg={1} > <Image className="p-1 rounded-circle bg-dark mx-auto d-block" style={{width: 100, height: 100}} src={project.image || ''} // 处理图片未加载的情况 fluid /> <ListGroup variant="flush" > <ListGroup.Item> <h3 className="rfs-10">{project.name || '加载中...'}</h3> {/* 修正class为className,添加默认值 */} </ListGroup.Item> <ListGroup.Item style={{fontSize: 12}}> <p>{project.description || ''}</p> </ListGroup.Item> </ListGroup> </Col> </Row> </div> ) } export default Project;
3. 确保列表页链接正确生成
在Projects组件中,生成详情页链接时要正确传递slug参数:
// Projects组件示例代码 import { Link } from 'react-router-dom'; // 每个项目项的链接 <Link to={`/projects/${project.slug}`}>{project.name}</Link>
后端修复(Django部分)
1. 修正urls.py路由拼写
把HTML实体编码的<slug:slug>改成正确的<slug:slug>,同时给每个URL设置唯一name避免冲突:
# urls.py from django.urls import path from .views import getRoutes, UserListView, ProjectListView, projectview urlpatterns = [ path('', getRoutes, name='routes'), path('users/', UserListView.as_view(), name='user-list'), path('projects/', ProjectListView.as_view(), name='project-list'), path('projects/<slug:slug>/', projectview, name='project-detail'), ]
2. 优化projectview视图的异常处理
添加项目不存在的捕获逻辑,返回404响应而非500错误:
# views.py @api_view(['GET']) def projectview(request, slug): # 直接接收slug参数,无需**kwargs try: project = Project.objects.get(slug=slug) serializer = ProjectSerializer(project) return Response(serializer.data) except Project.DoesNotExist: return Response({'error': '项目不存在'}, status=404)
3. 修正getRoutes中的路由示例
把错误的路由示例改成和实际一致:
# views.py中的getRoutes函数 routes = [ '/api/projects/', '/api/users/', '/api/projects/<slug:slug>/', '/api/users/<id>/', ]
验证修复
- 重启Django后端和React前端
- 访问项目列表页,点击项目链接,确认路径变为
http://localhost:3000/projects/skyscrapper - 检查控制台和终端,确认无报错,项目详情正常显示
内容的提问来源于stack exchange,提问作者Pavel Pshich
相关产品推荐
相关产品推荐

