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

Django实现处理完成后用户下载文件的问题求助

Django生成文件后下载报错:name 'WS_file_name' is not defined

需求流程

  • 用户在表单填写lastname、firstname并上传文件newfile
  • Django后台处理文件,生成名为WS_file_name+'.xlsx'的新文件
  • 处理完成后展示下载按钮
  • 用户点击按钮下载生成的文件

相关代码

views.py

from django.shortcuts import render  
from django.http import HttpResponse
def index(request):  
    if request.method == 'POST':
        student = StudentForm(request.POST, request.FILES)  
        if student.is_valid():
            handle_uploaded_file(request.FILES['file'])

            firstname= student.cleaned_data.get("firstname")
            lastname= student.cleaned_data.get("lastname")

            ### Processing ###
            WS_file_name = lastname + firstname + newfile
            Toollist_Raw = pd.read_excel(Toollist_path+Toollist_file_name)
            WS_file = xlsxwriter.Workbook(WS_file_name+'.xlsx')
            WS_file.close()
            file_source = WS_Path + WS_file_name+'.xlsx'
            Toollist_Raw.to_excel(file_source, sheet_name='CALM_Toollist',index=False)
            
            ### Process had completed, users can click download button to download the file ###
            context= {'username': firstname, 'version':lastname,}
            return render(request, 'template_Download.html', context)
       else:
            student = StudentForm()
            return render(request,"template_Form.html",{'form':student})



##### Download Functions #####
import os
from django.http import FileResponse
def download_file(request):
    # Define Django project base directory
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # Define file name
    filename = WS_file_name+'.xlsx'
    # Define the full file path
    filepath = BASE_DIR + '/Capital_Report_Website/Download_Files/Baseline_Cleanup_Toollist_vs_CALM_Download/' + filename +'.xlsx'
    return FileResponse(open(filepath, 'rb'), as_attachment=True)

template_Form.html

<form method="POST" class="post-form" enctype="multipart/form-data">  
            {% csrf_token %}  
            {{ form.as_p }}  
            <button type="submit" class="save btn btn-default">Generate Report</button>  
    </form>

template_Download.html

<h3>Hi, {{username}} your toollist {{version}} vs CALM report is completed.</h3>
<a href="http://localhost/toollistvscalm/download/">Download</a>

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('toollistvscalm/', views.index),
    path('toollistvscalm/download/', views.download_file),
]

报错信息

name 'WS_file_name' is not defined

问题原因

WS_file_name是index视图处理POST请求时的局部变量,download_file是独立的视图函数,无法直接访问该变量,导致报错。同时原代码中download_file的文件路径拼接重复添加了.xlsx后缀,也会导致文件找不到。

解决方案

方案一:使用Django Session传递文件名

  1. 修改index视图,将生成的文件名存入session:
# 在return render前添加
request.session['ws_file_name'] = WS_file_name
context= {'username': firstname, 'version':lastname,}
return render(request, 'template_Download.html', context)
  1. 修改download_file视图,从session中获取文件名并修正路径:
import os
from django.http import FileResponse, Http404
def download_file(request):
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # 从session获取文件名
    ws_file_name = request.session.get('ws_file_name')
    if not ws_file_name:
        raise Http404("File not found")
    
    filename = f"{ws_file_name}.xlsx"
    # 拼接正确路径(避免重复加.xlsx)
    filepath = os.path.join(BASE_DIR, 'Capital_Report_Website/Download_Files/Baseline_Cleanup_Toollist_vs_CALM_Download', filename)
    
    # 检查文件是否存在
    if not os.path.exists(filepath):
        raise Http404("File not found")
    
    return FileResponse(open(filepath, 'rb'), as_attachment=True, filename=filename)

方案二:通过URL传递文件名(更直观)

  1. 修改urls.py,给下载路径添加文件名参数:
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('toollistvscalm/', views.index),
    # 添加文件名参数
    path('toollistvscalm/download/<str:filename>/', views.download_file, name='download_file'),
]
  1. 修改index视图,将文件名传入模板上下文:
context= {
    'username': firstname, 
    'version':lastname,
    'ws_file_name': WS_file_name  # 添加文件名到上下文
}
return render(request, 'template_Download.html', context)
  1. 修改template_Download.html的下载链接,使用Django的URL反向解析传递文件名:
<h3>Hi, {{username}} your toollist {{version}} vs CALM report is completed.</h3>
<a href="{% url 'download_file' filename=ws_file_name %}">Download</a>
  1. 修改download_file视图,接收文件名参数并处理:
import os
from django.http import FileResponse, Http404
def download_file(request, filename):
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    full_filename = f"{filename}.xlsx"
    filepath = os.path.join(BASE_DIR, 'Capital_Report_Website/Download_Files/Baseline_Cleanup_Toollist_vs_CALM_Download', full_filename)
    
    if not os.path.exists(filepath):
        raise Http404("File not found")
    
    return FileResponse(open(filepath, 'rb'), as_attachment=True, filename=full_filename)

额外优化提示

原代码中使用xlsxwriter.Workbook创建文件后直接关闭,随后又用Toollist_Raw.to_excel写入内容,这会导致文件内容被覆盖或写入失败。可以简化为:

# 替换原Processing部分的代码
WS_file_name = lastname + firstname + newfile
file_source = os.path.join(WS_Path, f"{WS_file_name}.xlsx")
Toollist_Raw = pd.read_excel(os.path.join(Toollist_path, Toollist_file_name))
Toollist_Raw.to_excel(file_source, sheet_name='CALM_Toollist', index=False, engine='xlsxwriter')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:40:55