You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Django正确展示Docker卷中生成的MP4文件?

解决Django在Docker开发环境中无法提供MP4媒体文件的404问题

问题根源分析

请求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:13:19