如何让Django正确展示Docker卷中生成的MP4文件?
问题根源分析
请求URL带了多余的fergana_api/前缀(http://127.0.0.1:8000/fergana_api/files/36/movies/movie.mp4),但你的URL规则仅匹配^files/(?P<path>.*)$,导致路径不匹配。同时需确认Docker卷挂载是否正确映射到MEDIA_ROOT,以及媒体文件路径生成逻辑是否合理。
修复步骤
1. 修正媒体文件路径,移除多余前缀
当前View生成的movie_path是相对路径(files/36/movies/xxx.mp4),浏览器会基于当前页面URL(如/fergana_api/tests/36/xxx)将其解析为/fergana_api/files/...,引发路径不匹配。
方案一:在View中生成绝对路径
修改app/views.py,直接拼接带根路径前缀的媒体地址:
from django.conf import settings class SingleTestView(View): def get(self, request, test_session_id, test_name): run = Runner.objects.get(id=test_session_id) movie_filename = test_name.replace('-', '_') + '.mp4' # 用MEDIA_URL拼接绝对路径,确保前缀正确 movie_path = f"{settings.MEDIA_URL}{test_session_id}/movies/{movie_filename}" context = { 'movie_path': movie_path } return render(request, "presenter/single_test.html", context)
方案二:在模板中强制使用绝对路径
若不想修改View,直接给模板中的路径添加根目录前缀:
<video width="320" height="240" controls> <source src="/{{ movie_path }}" type="video/mp4"> </video>
2. 修正Docker卷挂载,匹配MEDIA_ROOT
你的MEDIA_ROOT是/var/web/media/,但当前docker-compose仅挂载了static-data:/vol/web,需调整卷挂载路径:
services: app: build: context: . dockerfile: fergana-api.dockerfile args: - DEV=true ports: - '8000:8000' volumes: - ./fergana_api:/fergana_api - static-data:/var/web # 直接挂载到MEDIA_ROOT的父目录 volumes: static-data:
如果媒体文件存储在主机本地目录,也可直接绑定挂载:
volumes: - ./fergana_api:/fergana_api - ./path/to/host/media:/var/web/media # 主机媒体目录直接映射到容器MEDIA_ROOT
3. 验证开发环境媒体服务配置
确保project/url.py中的媒体服务配置正确,且DEBUG=True:
from django.conf import settings from django.conf.urls.static import static if settings.DEBUG: urlpatterns += static( settings.STATIC_URL, document_root=settings.STATIC_ROOT ) urlpatterns += static( settings.MEDIA_URL, document_root=settings.MEDIA_ROOT )
static()函数会自动匹配MEDIA_URL前缀,只要MEDIA_URL为files/,就能正确处理/files/...路径。
4. 验证容器内文件路径
进入容器确认文件存在于指定路径:
docker-compose exec app ls /var/web/media/36/movies/
若文件不存在,检查文件生成逻辑是否将文件写入了MEDIA_ROOT目录。
测试验证
重启Docker容器后重新测试:
docker-compose down && docker-compose up --build
此时视频请求URL应变为http://127.0.0.1:8000/files/36/movies/movie.mp4,可正常加载。
内容的提问来源于stack exchange,提问作者user11419808

