要实现通过 Django 框架读取文件并返回给前端页面下载的功能,可以使用 Django 的 FileResponse 或 StreamingHttpResponse。为了处理文件名乱码问题,可以使用 urllib.parse.quote 对文件名进行编码。
以下是完整的代码实现:
import os
from django.http import FileResponse, HttpResponse
from urllib.parse import quote
def generator_bid_document(request):
# 文件路径
file_path = r"C:\Leon\python_project\AI_Rest_API\work\ready_call_ai\5b19f638-c9b7-4817-b3c0-67b5c64c7f22\计量器具技术服务竞标采购文件_20250417_105006_deepseek-r1-1.5b_with_images.docx"
# 检查文件是否存在
if not os.path.exists(file_path):
return HttpResponse("文件不存在", status=404)
# 获取文件名并处理乱码问题
file_name = os.path.basename(file_path)
encoded_file_name = quote(file_name) # 对文件名进行 URL 编码
# 使用 FileResponse 返回文件流
try:
response = FileResponse(open(file_path, 'rb'))
response['Content-Disposition'] = f'attachment; filename="{encoded_file_name}"'
response['Content-Type'] = 'application/octet-stream'
return response
except Exception as e:
return HttpResponse(f"文件读取失败: {str(e)}", status=500)
代码说明:
- 文件路径:
file_path是你要读取的文件的完整路径。 - 文件存在性检查:使用
os.path.exists检查文件是否存在,如果不存在则返回 404 错误。 - 文件名编码:使用
urllib.parse.quote对文件名进行 URL 编码,以解决中文文件名乱码问题。 - FileResponse:使用
FileResponse返回文件流,FileResponse是 Django 提供的一个高效处理文件下载的类。 - Content-Disposition:设置
Content-Disposition头,告诉浏览器将文件作为附件下载,并指定文件名。 - Content-Type:设置
Content-Type为application/octet-stream,表示这是一个二进制文件流。
注意事项:
• 如果文件较大,建议使用 StreamingHttpResponse 来避免内存占用过高的问题。
• 如果文件路径是动态的,可以通过 request 参数传递文件路径,并在代码中进行验证和处理。
使用 StreamingHttpResponse 的版本(适用于大文件):
import os
from django.http import StreamingHttpResponse, HttpResponse
from urllib.parse import quote
def generator_bid_document(request):
# 文件路径
file_path = r"C:\Leon\python_project\AI_Rest_API\work\ready_call_ai\5b19f638-c9b7-4817-b3c0-67b5c64c7f22\计量器具技术服务竞标采购文件_20250417_105006_deepseek-r1-1.5b_with_images.docx"
# 检查文件是否存在
if not os.path.exists(file_path):
return HttpResponse("文件不存在", status=404)
# 获取文件名并处理乱码问题
file_name = os.path.basename(file_path)
encoded_file_name = quote(file_name) # 对文件名进行 URL 编码
def file_iterator(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
try:
response = StreamingHttpResponse(file_iterator(file_path))
response['Content-Disposition'] = f'attachment; filename="{encoded_file_name}"'
response['Content-Type'] = 'application/octet-stream'
return response
except Exception as e:
return HttpResponse(f"文件读取失败: {str(e)}", status=500)
在这个版本中,file_iterator 函数以流的方式读取文件,避免一次性将整个文件加载到内存中,适合处理大文件。

2785

被折叠的 条评论
为什么被折叠?



