Django的form表單之檔案上傳
在生成input標簽的時候可以指定input標簽的型別為file型別
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>{{ error_message }}</h4>
<form action="/index/" method="post">
{% csrf_token %}
<p><input type="file" name="up_file"></p>
<input type="submit">
</form>
</body>
</html>
此時,在網頁上頁示如下

如果網頁上提交的是用戶名和密碼等,通過鍵值對發送到服務端,
一組鍵值代表一個標簽及標簽對應的值,
在網頁上選擇一張圖片,并使用post方式提交,在服務端列印request.POST
def index(request):
if request.method=="POST":
print(request.POST)
return render(request,"index.html",locals())
列印的資訊如下:
<QueryDict: {'csrfmiddlewaretoken': ['opmSmENIrgdGJJN'], 'up_file': ['1.png']}>
提交的檔案名也在這個字典中,取出這個檔案名
def index(request):
if request.method=="POST":
print(request.POST.get("up_file"))
print(type(request.POST.get("up_file")))
return render(request,"index.html",locals())
列印結果如下:
1.png
<class 'str'>
想取出的是上傳的檔案,然而取出來的卻是上傳的檔案的檔案名
由此可知,上傳的檔案沒有跟form表單提交的資料在一起
因為上傳的檔案通常大小比較大,所以Django默認會把上傳的檔案放在一個具體的檔案夾中
列印request.FILES的資訊
def index(request):
if request.method=="POST":
print(request.POST.get("up_file"))
print(type(request.POST.get("up_file")))
print("files:",request.FILES)
return render(request,"index.html",locals())
列印結果如下
1.png
<class 'str'>
files: <MultiValueDict: {}>
request.FILES列印的結果是一個空的字典,問題出在上傳檔案的方式上
由于上傳檔案時在客戶端與服務端傳輸的是二進制資料,與字串資料不一樣,
傳輸二進制資料,不管是在form表單,還是在Ajax中,都有自己的傳輸方式,
在form表單中,上傳檔案時要使用分片傳輸的方式,
修改index.html檔案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>{{ error_message }}</h4>
<form action="/index/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p><input type="file" name="up_file"></p>
<input type="submit">
</form>
</body>
</html>
重新上傳檔案,在服務端列印資訊如下
None
<class 'NoneType'>
files: <MultiValueDict: {'up_file': [<InMemoryUploadedFile: 1.png (image/png)>]}>
根據列印結果,request.FILES中可以看到上傳的檔案
列印結果是一個字典型別,字典的鍵是form表單中定義的標簽的name屬性值,而其值是所上傳的檔案的物件
列印上傳檔案的物件
def index(request):
if request.method=="POST":
print("files:",request.FILES.get("up_file"))
print(type(request.FILES.get("up_file")))
return render(request,"index.html",locals())
列印結果
files: 1.png
<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
結果顯示所取得的檔案的型別是一個在記憶體中的上傳檔案
獲取上傳檔案在記憶體中的名字
def index(request):
if request.method=="POST":
print(type(request.FILES.get("up_file")))
file_obj=request.FILES.get("up_file")
print(file_obj.name)
return render(request,"index.html",locals())
列印結果如下
<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
1.png
既然知道了檔案在記憶體中的名字,就可以在服務端寫入這個檔案
def index(request):
if request.method=="POST":
file_obj=request.FILES.get("up_file")
f1=open(file_obj.name,"wb")
for i in file_obj.chunks():
f1.write(i)
f1.close()
return render(request,"index.html",locals())
再次選擇上傳檔案,提交后,就可以在服務端后臺看到所上傳的檔案
可以在settings.py檔案中設定上傳檔案的路徑,或者在打開檔案句柄的時候進行路徑拼接來把上傳的檔案保存在指定的目錄下
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/136648.html
標籤:Python
上一篇:Python 字串操作常用知識點
