[英]How to let user download a file after the process is completed in Django?
我是Django的初學者。我正在嘗試讓用戶在完成特定過程后下載文件。
這是view.py
。 該過程完成后會顯示下載按鈕。 用戶可以通過單擊下載按鈕下載名為 WS_file_name+'.xlsx' 的文件。
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
,用於調用views.py
中的函數。
urlpatterns = [
path('admin/', admin.site.urls),
path('toollistvscalm/', views.index),
path('toollistvscalm/download/', views.download_file),
]
單擊下載按鈕后顯示以下錯誤。
name 'WS_file_name' is not defined
畢竟我想要的整個過程如下。
lastname
, firstname
並在表單中上傳文件newfile
。newfile
獲取新文件並在后端執行創建新文件的過程(文件名必須是WS_file_name+'.xlsx'
)。WS_file_name+'.xlsx'
的按鈕。WS_file_name+'.xlsx'
。我已經嘗試了一切來修復它,但都是徒勞的。 請幫我。
好的,問題是,在您的 function download_file
中未定義變量WS_file_name
。 由於 function download_file
無法與 function index
交互(至少您設置它的方式),您需要使用與您將文件存儲在 function index
中時給它的文件名完全相同的文件名來填充變量WS_file_name
。
那你應該沒問題!
我會給你一個應該工作的硬編碼文件名的例子:
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 = "hardcoded_filename" # HERE FILENAME
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 = "hardcoded_filename" +'.xlsx' # HERE SAME FILENAME
# 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)
但請考慮以下幾點:這需要您將所有這些文件存儲在您的主機上。 我覺得你應該將### Processing ###
部分移動到download_file
function。因此你不需要將文件存儲在你的機器上,你可以“即時”將它呈現給用戶。
由於 OP 想要動態文件名 - 你在那里 go ...
模型.py
class Student(models.Model):
firstname = models.CharField(max_lenght=30)
lastname = models.CharField(max_lenght=30)
path_to_xlsx = models.FilePathField(null=True, blank=True) # don't know if this works, or just put a default in.
視圖.py
def index(request):
[...]
if student.is_valid():
the_student = Student.objects.get(pk=<your-student>) # somehow grab your student here
[... file processing ...]
the_student.path_to_xlsx = os.path.join(path_to_your_file)
the_student.save()
the_student = student.save()
def download_file(request):
[...]
the_student = Student.objects.get(pk=<your-student>) # somehow grab your student here
return FileResponse(open(the_student.path_to_xlsx, 'rb'), as_attachment=True)
但我仍然不認為這很好,因為 excel 文件會污染主機的文件系統和存儲
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.