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

Django本地文件下载路径问题求助

Django本地文件下载功能修复方案

1. HTML模板URL标签错误修正

你当前的a标签{% url 'download/path' %}写法不符合Django路由规则,正确的写法需要传入路由名称和对应的路径参数:

<div class="com">
    {{plik.localisation}} <a href="{% url 'download' path=plik.localisation %}" class="button">download</a>
</div>

这里download是你在urls.py中定义的路由name,path=plik.localisation用于将文件路径参数传递给视图函数。

2. 视图函数优化与下载行为调整

  • 你当前使用Content-Disposition: inline是让浏览器在线打开PDF,若要触发本地下载,需改为attachment;
  • 推荐使用Django原生的FileResponse替代HttpResponse,它更适合处理文件流,性能更优:
from django.http import FileResponse, Http404
import os
from django.conf import settings

def download(request, path):
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path) and os.path.isfile(file_path):
        return FileResponse(open(file_path, 'rb'), as_attachment=True, filename=os.path.basename(file_path))
    raise Http404

3. 路径合法性校验

确保plik.localisation存储的是相对于MEDIA_ROOT的相对路径,而非绝对路径或包含../的层级跳转路径(后者存在安全风险)。比如MEDIA_ROOT为/home/user/media/,那么plik.localisation应是docs/report.pdf这类格式。

4. 安全加固(防止路径遍历攻击)

为避免恶意用户通过构造路径访问MEDIA_ROOT外的文件,可在视图中增加路径校验逻辑:

from django.http import FileResponse, Http404
import os
from django.conf import settings

def download(request, path):
    # 规范化路径,去除相对层级跳转
    normalized_path = os.path.normpath(path)
    if normalized_path.startswith('..'):
        raise Http404
    
    file_path = os.path.join(settings.MEDIA_ROOT, normalized_path)
    # 二次校验确保文件在MEDIA_ROOT范围内
    if not file_path.startswith(settings.MEDIA_ROOT):
        raise Http404
    
    if os.path.exists(file_path) and os.path.isfile(file_path):
        return FileResponse(open(file_path, 'rb'), as_attachment=True, filename=os.path.basename(file_path))
    raise Http404

内容的提问来源于stack exchange,提问作者Robert Wyszynski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:45:57