写在前面
作者在Python 3.6.1 Django 2.1环境下开发Web应用,主要参考
Django 搭建文件接收服务器,博文大部分内容引用于之。然而,因为Django版本不同,部分操作存在差异。本文主要记录作者对教程的实现过程和遇到的问题。
下文中,Python3的安装路径记为"Python36".
本文内容
上传文件到指定目录下,并在新页面中显示文件内容。
实现过程
1.在testdj/templates下放一个upload.html,为主页的定义:
<!DOCTYPEhtml>
<htmllang="en">
<head>
<meta charset="UTF-8">
<title>Upload Text</title>
</head>
<body>
<h1 align="center">Upload .txt file</h1>
<form enctype="multipart/form-data" action="/uploadfile/" method="post">
<input type="file" name="myfile"/>
<br/>
<input type="submit" value="upload"/>
</form>
</body>
</html>
注解:在主页是upload.html的情况下,定义两个input控件,分别用于选择文件和上传。用post方法提交文件之后,转到uploadfile页面显示指定内容。
主页的布局如图所示:
2.URL的修改:
from django.urls import *
from testdj.view import *
urlpatterns = [
path('', showUploadPage),
path('uploadfile/', uploadFile)
]
注解:主页对应的方法是showUploadPage(定义在view.py,用于直接显示主页HTML的内容),uploadfile页面对应的方法是uploadFile,在下文细说。
3.修改testdj/testdj/settings.py,修改 TEMPLATES 中的 DIRS :
TEMPLATES = [
{
...
'DIRS': [BASE_DIR + "/templates"],
...
},
]
4.修改 testdj/testdj/view.py
主页的显示(和本系列(2)一样):
from django.shortcuts import render_to_response
def showUploadPage(request):
return render_to_response("upload.html")
上传文件的实现:后端建立文件,把前端接收到的数据按分块写入
def uploadFile(request):
if request.method == "POST": # Notice: Capitalize
# get file
file = request.FILES.get("myfile",None) # Get Upload
if not file:
return HttpResponse("no files for upload!")
# make save path: uploaded file is saved in testdj/receive
path = "receive"
if not os.path.exists(path):
os.makedirs(path)
# save file: write in by chucks
destination=open(os.path.join(path,file.name),'wb')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
...
子界面显示的实现:
第一种方法,直接打开后端保存的文件,把内容读出,把字符串提供给浏览器。
def uploadFile(request):
...
with open(os.path.join(path,file.name), mode='r', encoding = 'utf-8') as f:
c = f.read()
return HttpResponse(c)
第二种方法,把文件流提供给浏览器。
def uploadFile(request):
...
from django.http import StreamingHttpResponse
def file_iterator(file_name, chunk_size=512):
with open(file_name) as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break
response = StreamingHttpResponse(file_iterator(os.path.join(path,file.name)))
进一步可参考Django实现下载文件功能。
效果
进入 testdj 目录,输入以下命令启动服务器:
python manage.py runserver
访问127.0.0.1:8000,实现上传,在后继页面显示内容:
同时上传的1.txt保存在testdj/receive,即后端指定路径下。