Bootcamp毕业项目:React.JS+Django音视频上传功能实现咨询
音视频上传功能实现方案建议(React + Django)
前端实现(React)
- 文件选择与基础校验
可以用原生的<input type="file" accept="audio/*,video/*" multiple />实现基础文件选择,也可以用react-dropzone库快速开发拖拽上传功能。前端先做一层校验:通过accept属性限制文件类型,通过file.size限制文件大小(比如视频不超100MB、音频不超50MB),减少无效请求。 - 上传进度与状态反馈
用Fetch API或XMLHttpRequest发送请求时,监听进度事件实现进度条。比如用XHR的onprogress事件实时获取上传进度,给用户展示“上传中”“上传成功”“上传失败”的状态提示。 - 请求封装示例
注意:不要手动设置const handleUpload = async (file) => { const formData = new FormData(); formData.append('media_file', file); try { const response = await fetch('/api/upload-media/', { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value }, body: formData }); const data = await response.json(); console.log('上传成功', data); } catch (error) { console.error('上传失败', error); } };Content-Type,浏览器会自动根据FormData生成正确的请求头。
后端实现(Django)
- 基础配置
在settings.py中配置媒体文件存储路径:
开发阶段在MEDIA_ROOT = BASE_DIR / 'media' MEDIA_URL = '/media/'urls.py中添加媒体文件的访问路由:from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 其他业务路由 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - 模型设计(可选)
如果需要存储文件元数据(上传者、类型、时间等),定义如下模型:from django.db import models from django.contrib.auth.models import User class MediaFile(models.Model): FILE_TYPE_CHOICES = ( ('audio', '音频'), ('video', '视频'), ) file = models.FileField(upload_to='media_files/%Y/%m/%d/') file_type = models.CharField(max_length=10, choices=FILE_TYPE_CHOICES) uploaded_at = models.DateTimeField(auto_now_add=True) uploader = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) def save(self, *args, **kwargs): # 自动判断文件类型 ext = self.file.name.split('.')[-1].lower() if ext in ['mp3', 'wav', 'flac']: self.file_type = 'audio' elif ext in ['mp4', 'avi', 'mov']: self.file_type = 'video' super().save(*args, **kwargs) - 上传视图实现
编写处理上传的视图,做后端二次校验并保存文件:
在from django.http import JsonResponse from .models import MediaFile import os def upload_media(request): if request.method == 'POST' and request.FILES.get('media_file'): media_file = request.FILES['media_file'] # 校验文件大小 if media_file.size > 100 * 1024 * 1024: return JsonResponse({'error': '文件大小超过100MB限制'}, status=400) # 校验文件扩展名 allowed_exts = {'mp3', 'wav', 'flac', 'mp4', 'avi', 'mov'} ext = media_file.name.split('.')[-1].lower() if ext not in allowed_exts: return JsonResponse({'error': '不支持该文件类型'}, status=400) # 保存到模型 obj = MediaFile.objects.create(file=media_file, uploader=request.user if request.user.is_authenticated else None) return JsonResponse({ 'success': True, 'file_url': obj.file.url, 'file_id': obj.id }) return JsonResponse({'error': '无效请求'}, status=400)urls.py中挂载视图:from .views import upload_media urlpatterns = [ path('api/upload-media/', upload_media, name='upload-media'), # 其他路由 ]
关键优化与注意事项
- 大文件分片上传:如果要支持GB级视频,建议实现分片上传。前端把文件切成5MB左右的小块,依次上传到后端,后端接收后拼接成完整文件,避免单次请求超时。
- 文件转码:如果需要统一格式(比如转成MP4/MP3),可以集成FFmpeg工具,在文件保存后调用FFmpeg命令转码,转码完成后替换原文件或生成新的转码文件。
- 权限控制:如果是用户专属上传,要在视图中验证用户身份(Session或JWT),确保只有登录用户能上传,且只能访问自己的文件。
- 生产环境配置:生产环境不要用Django自带的本地存储,建议配置云存储(如OSS、S3),通过
django-storages库对接,提升文件访问性能和可靠性。
内容的提问来源于stack exchange,提问作者jamesscott
相关产品推荐
相关产品推荐

