如何在React组件中用Axios调用DRF关联API并展示视频路径?
解决方案
1. Axios调用关联API的实现(CourseDetails组件)
方式一:分步调用(先拉取课程,再拉取对应视频)
如果你的DRF接口是分开设计的,比如:
- 获取单课程详情:
GET /api/courses/{courseId}/ - 获取该课程下的视频列表:
GET /api/videos/?course_id={courseId}
可以在React组件中通过useEffect先获取课程数据,再用返回的课程ID请求关联视频:
import { useState, useEffect } from 'react'; import axios from 'axios'; import { useParams } from 'react-router-dom'; // 用React Router v6的useParams获取路由参数 const CourseDetails = () => { const [course, setCourse] = useState(null); const [videos, setVideos] = useState([]); const [loading, setLoading] = useState(true); const { courseId } = useParams(); // 从路由参数中获取课程ID useEffect(() => { const fetchData = async () => { try { // 第一步:获取课程详情 const courseRes = await axios.get(`/api/courses/${courseId}/`); setCourse(courseRes.data); // 第二步:用课程ID获取关联视频 const videosRes = await axios.get(`/api/videos/?course_id=${courseId}`); setVideos(videosRes.data); } catch (err) { console.error('数据获取失败:', err); } finally { setLoading(false); } }; fetchData(); }, [courseId]); if (loading) return <div>加载中...</div>; if (!course) return <div>课程不存在</div>; // 后续渲染逻辑 };
方式二:使用DRF嵌套路由(更高效)
如果你的DRF通过rest_framework_nested库配置了嵌套路由,或者在课程序列化器中嵌套了视频序列化器,就可以通过一个接口同时获取课程及关联视频,比如接口地址为GET /api/courses/{courseId}/videos/,或者课程接口返回的字段中直接包含videos数组。这种情况下只需一次请求:
useEffect(() => { const fetchCourseWithVideos = async () => { try { const res = await axios.get(`/api/courses/${courseId}/`); setCourse(res.data); setVideos(res.data.videos); // 假设课程接口返回的data中包含videos数组 } catch (err) { console.error('数据获取失败:', err); } finally { setLoading(false); } }; fetchCourseWithVideos(); }, [courseId]);
2. JSX中展示视频路径的正确写法
情况A:DRF返回完整媒体URL
如果Django配置了MEDIA_URL且返回的视频路径是完整URL(比如http://your-domain/media/videos/xxx.mp4),直接赋值给src即可:
{videos.map(video => ( <div key={video.id} className="video-item"> <h3>{video.title}</h3> <video controls width="600"> <source src={video.video_url} type="video/mp4" /> 你的浏览器不支持视频播放 </video> </div> ))}
情况B:DRF返回相对路径
如果返回的是相对路径(比如/media/videos/xxx.mp4),需要拼接后端域名:
const BACKEND_BASE_URL = 'http://localhost:8000'; // 生产环境替换为实际后端域名 {videos.map(video => ( <div key={video.id} className="video-item"> <h3>{video.title}</h3> <video controls width="600"> <source src={`${BACKEND_BASE_URL}${video.video_url}`} type="video/mp4" /> 你的浏览器不支持视频播放 </video> </div> ))}
3. 前端URL形式
假设使用React Router配置路由,CourseDetails组件的前端URL通常设计为:
- 格式:
/courses/:courseId
例如访问ID为1的课程详情页,完整URL为http://your-frontend-domain/courses/1
路由配置示例(React Router v6):
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import CourseDetails from './components/CourseDetails'; function App() { return ( <Router> <Routes> <Route path="/courses/:courseId" element={<CourseDetails />} /> {/* 其他路由配置 */} </Routes> </Router> ); }
内容的提问来源于stack exchange,提问作者Manali
相关产品推荐
相关产品推荐

