前端隱藏input,實(shí)現(xiàn)Django文件上傳的一個(gè)例子

背景

某運(yùn)維平臺(tái)有一個(gè)業(yè)務(wù)需求,需要周期性對(duì)某個(gè)導(dǎo)出的文件進(jìn)行透視分析。通過在現(xiàn)有平臺(tái)上添加上傳文件功能,服務(wù)器后臺(tái)收到文件后完成透視分析流程,跳轉(zhuǎn)到圖表等形式的報(bào)告頁。
本文介紹如何利用Django完成文件上傳功能,并且因?yàn)榻y(tǒng)一風(fēng)格和美化的關(guān)系,前臺(tái)隱藏input標(biāo)簽。

Django部分

views.py

views中兩個(gè)處理邏輯:file_upload函數(shù)負(fù)責(zé)提供上傳頁面(此函數(shù)正式平臺(tái)不需要,后面講到);upload負(fù)責(zé)接收文件并完成實(shí)際的文件處理,返回生成的報(bào)告。

def file_upload(request):
    return render(request, 'file_upload_input_submit.html')
    
def upload(request):
    f = request.FILES['upload_file']
    filename = f.name
    with open('upload\\{}'.format(filename), 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    
    # do something with the file uploaded
    report = '<h1>UPLOADED FILE:{}</h1><h2>REPORT FROM FILE CONTENTS</h2>'.format(filename)
    
    # render report
    return render_to_response('report.html', {'report': report})

urls.py

添加兩個(gè)地址路由:file_upload地址路由到views.file_upload,upload地址路由到views.upload。

from django.contrib import admin
from django.urls import path
import app.views as views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('file_upload/', views.file_upload),
    path('upload/', views.upload),
]

TEMPLATES模板

最普通的上傳頁(顯示input)

僅完成上傳功能的file_upload_input_submit.html模板,通過input按鈕與用戶交互,其body部分代碼如下:

<body>
    <form enctype="multipart/form-data" name='form' method="post" action="/upload/">{% csrf_token %}
    <input type="file" name="upload_file" onChange="document.forms['form'].submit();"/>
</body>

留著input就是很丑,效果如下:


使用input上傳文件

隱藏input

file_upload_hide_input_with_function.html模板中隱藏了input,通過超鏈接調(diào)用click_upload函數(shù)→模擬點(diǎn)擊input→彈出文件選擇對(duì)話框,選取文件→觸發(fā)onChange事件→提交表單→訪問upload地址,代碼如下:

<head>
    <title>文件上傳</title>
    <script>
        function click_upload() {
            document.getElementById('input').click();
        }
    </script>
</head>

<body>
    <form enctype="multipart/form-data" name='form' method="post" action="/upload/">{% csrf_token %}
    <input type="file" id='input' name="upload_file" onChange="document.forms['form'].submit();" style='display:none'/>
    <a href='javascript:click_upload();' >UPLOAD</>
</body>

效果如下:


使用超鏈接代替input

簡化html

其實(shí)前面一個(gè)模板的function中就一行代碼,如果覺得一個(gè)函數(shù)就一行代碼顯得比較啰嗦,可以將這行代碼直接寫到a標(biāo)簽的href中。寫成函數(shù)在整個(gè)前端中可以保持代碼風(fēng)格統(tǒng)一,而嵌套在html中則比較簡潔,兩者沒有好壞之分,視具體應(yīng)用場(chǎng)景。

<body>
    <form enctype="multipart/form-data" name='form' method="post" action="/upload/">{% csrf_token %}
    <input type="file" id='input' name="upload_file" onChange="document.forms['form'].submit();" style='display:none'/>
    <a href='javascript:document.getElementById("input").click();' >UPLOAD</a>
</body>

嵌入正式平臺(tái)

正式平臺(tái)左側(cè)是一堆功能鏈接,因此不需要單獨(dú)的上傳頁。將表單和超鏈接部分的代碼插入平臺(tái)的主頁即可。


側(cè)邊欄中添加上傳文件的超鏈接

上傳文件完成后跳轉(zhuǎn)到報(bào)告演示頁:


跳轉(zhuǎn)到報(bào)告演示頁

關(guān)于文件名

一開始為上傳到服務(wù)器的文件定了一個(gè)臨時(shí)的文件名,后來想使用文件原來的名字在服務(wù)器端命名。使用搜索引擎查找了一下,得到的方法是在js函數(shù)中截取上傳路徑中分隔符的最后一部分作為文件名參數(shù)傳遞給后臺(tái),比如在StackOverflow上某回答中的代碼如下:

function uploadOnChange() {
    var filename = this.value;
    var lastIndex = filename.lastIndexOf("\\");
    if (lastIndex >= 0) {
        filename = filename.substring(lastIndex + 1);
    }
    document.getElementById('filename').value = filename;}

這也是為什么我在嘗試隱藏input時(shí)首先單獨(dú)寫了個(gè)函數(shù)的原因(原本的函數(shù)是不止1行的)。后來翻Django文檔時(shí)看到,UploadedFile 類其實(shí)是有name屬性的:

name = property(_get_name, _set_name)

所以在views.upload中直接對(duì)文件調(diào)用該屬性即可,沒有必要用js那么麻煩。

參考資料

https://docs.djangoproject.com/en/2.1/topics/http/file-uploads/
https://docs.djangoproject.com/en/2.1/_modules/django/core/files/uploadedfile/
http://www.cnblogs.com/linxiyue/p/4038436.html
https://stackoverflow.com/questions/5480934/pass-filename-from-file-upload-to-text-field

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容