簡體   English   中英

Django進程完成后如何讓用戶下載文件?

[英]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

畢竟我想要的整個過程如下。

  1. 用戶填寫lastnamefirstname並在表單中上傳文件newfile
  2. newfile獲取新文件並在后端執行創建新文件的過程(文件名必須是WS_file_name+'.xlsx' )。
  3. 該過程完成后,它會顯示供用戶下載文件WS_file_name+'.xlsx'的按鈕。
  4. 用戶點擊按鈕下載文件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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM