学习笔记,仅供参考 文件上传 上传须知 文件上传必须为POST提交方式,在文件上传时,表单form中必须有带有enctype="multipart/form-data" 参数,才会包含文件内容数据。 在
学习笔记,仅供参考
文件上传
上传须知
- 文件上传必须为POST提交方式,在文件上传时,表单<form>中必须有带有enctype="multipart/form-data" 参数,才会包含文件内容数据。
- 在表单中,我们通常用<input type="file" name="xxx">标签上传文件,type="file"用于生产一个表单控件,而name="xxx"与服务器端相联系。
- 在服务器端,我们可以通过request.FILES['xxx'] 返回的文件流对象,拿到name="xxx"所对应的上传文件。
- 若我们用变量名file接收request.FILES['xxx'],即file=request.FILES['xxx'] ,此时,file就会绑定一个文件流对象,我们可以通过file.name 获取上传文件的文件名,通过file.file 获取上传文件的字节流对象(相当于f=open("文件名", rb)中f获取的对象)。
- 如上传文件为图片类型,则可以定义成models.ImageField类型
- image_file = models.ImageField(upload_to='images/')
- 如果属性类型为ImageField需要安装Pilow,pip install Pillow
- 上传文件的表单书写方式
<html>
<head>
<title>文件上传</title>
<meta charset="utf-8">
</head>
<body>
<h1>上传文件</h1>
<form method="post" action="/upload/" enctype="multipart/form-data">
<input type="file" name="myfile"/><br>
<input type="submit" value="上传">
</form>
</body>
</html>
举个例子
现在,在这个例子中,我想实现文件的上传。
现在,我们在mywebsite_bookstore项目下的模板文件夹templates下创建一个upload.html文件:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<h2>文件上传</h2>
<form action="/upload/" method="POST" enctype="multipart/form-data">
<input type="file" name="myfile">
<input type="submit" value="上传">
</form>
</body>
</html>
在主视图模块views.py中添加一个视图函数:
def on_upload(request):if request.method == "GET":
return render(request, "upload.html")
elif request.method == "POST":
file = request.FILES['myfile']
html = "上传的文件为:{} <br> 文件名为{}".format(file, file.name)
return HttpResponse(html)
注意,我们获取的file对象不在我的磁盘上,而在内存中。
在主urls.py模块中添加一个路由:
from django.urls import re_pathfrom django.contrib import admin
from django.conf.urls import include
from . import views
urlpatterns = [
re_path(r'^admin/', admin.site.urls),
re_path(r'^upload/$',views.on_upload),
]
现在,我们向http://127.0.0.1:8000/upload/发起请求,并选择要上传的文件:
点击上传,得到如下页面:
现在,我想将上传的图片TX.jpg保存在mywebsite_bookstore项目下的static/image文件夹下。
我们修改一下views.py文件:
def on_upload(request):if request.method == "GET":
return render(request, "upload.html")
elif request.method == "POST":
file = request.FILES['myfile']
html = "上传的文件为:{} <br> 文件名为{}".format(file, file.name)
with open(r"F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_bookstore\static\image\\"
+ file.name, 'wb') as f:
b = file.file.read()
#读取缓存文件的内容
f.write(b)
return HttpResponse(html)
注意,这里的文件保存路径为绝对路径。我们也可以通过BASE_DIR来写保存文件的绝对路径(BASE_DIR会告诉我们项目所在的绝对路径)。
要做这件事,我们就需要在settings.py中自定义一个文件保存路径:
#自定义变量UPLOAD_DIR用于绑定上传文件的保存路径UPLOAD_DIR = os.path.join(BASE_DIR, 'static/image')
在主views.py中导入当前项目的配置文件settings.py,并修改视图函数on_upload:
from django.conf import settingsimport os
def on_upload(request):
if request.method == "GET":
return render(request, "upload.html")
elif request.method == "POST":
file = request.FILES['myfile']
html = "上传的文件为:{} <br> 文件名为{}".format(file, file.name)
with open(os.path.join(settings.UPLOAD_DIR, file.name), 'wb') as f:
b = file.file.read()
f.write(b)
return HttpResponse(html)
一般情况下,我们的数据库中不会保存文件本身,而只保存文件的一些信息(比如文件名和文件保存路径)。
我们向http://127.0.0.1:8000/upload/发起请求,并上传文件,查看一下我们的F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_bookstore\static\image\路径下是否有TX.jpg文件:
Very Well !