用户可以通过浏览器将图片等文件传至网站
二、场景- 用户上传头像
- 上传流程性的文档[pdf,txt等]
- 文件上传必须为POST提交方式
- 表单
<form>
中文件上传时必须有带有enctype = "multipart/formdata"
时才会包含文件内容数据 - 表单中用
<input type="file" name="xxx">
标签上传文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/test_upload" method="post" enctype="multipart/form-data">
<p><input type="text" name="title"></p>
<p><input type="file" name="file"></p>
<p><input type="submit" value="上传"></p>
</form>
</body>
</html>
四、上传规范 - 后端【Django】
4.1. 获取内容
视图函数中,用request.FILES
取文件框的内容
file = request.FILES['xxx']
说明:
- FILES的key对应页面中file框的name值
- file绑定文件流对象
- file.name文件名
- file.file文件的字节流数据
4.2. 配置路径
配置文件的访问路径和存储路径
在setting.py中设置MEDIA相关配置
Django把用户上传的文件,统称为media资源
# file : setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
4.3. 绑定路径
MEDIA_URL和MEDIA_ROOT需要手动绑定
步骤:主路由中添加路由
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
说明:等价于做了MEDIA_URL开头的路由,Django接到该特征请求后去MEDIA_ROOT路径查找资源
五、文件写入方案5.1. 传统的open方式
@csrf_exempt
def upload_view(request):
if request.method == 'GET':
return render(request, 'test_upload.html')
elif request.method == 'POST':
# 取文件数据
a_file = request.FILES['file']
print("上传文件名是:", a_file.name)
# 拼接存储绝对路径
filename = os.path.join(settings.MEDIA_ROOT, a_file.name)
with open(filename, 'wb') as f:
# a_file.file 文件数据
# a_file.file.read() 读出来
data = a_file.file.read()
f.write(data)
return HttpResponse("接收文件:" + a_file.name + "成功")
5.2. 优化 - 借助ORM
借助M层,在数据库中搞一个字段,字段不存储文件本身,字段用来存储文件相对路径,
字段:FileFieId(upload = '子目录名')
def test_upload(request):
if request.method == 'GET':
return render(request, 'test_upload.html')
elif request.method == 'POST':
title = request.POST['title']
file = request.FILES['file']
Content.objects.create(title=title, file=file)
return HttpResponse("upload is ok")
测试:
-
创建应用
$ python3 manage.py startapp upload_app
-
注册应用
-
数据模型
-
迁移
-
视图函数
def test_upload(request): if request.method == 'GET': return render(request, 'test_upload.html') elif request.method == 'POST': title = request.POST['title'] file = request.FILES['file'] Content.objects.create(title=title, picture=file) return HttpResponse("upload is ok")
-
界面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上传文件</title> </head> <body> <form action="/test_upload" method="post" enctype="multipart/form-data"> {% csrf_token %} <p><input type="text" name="title"></p> <p><input type="file" name="file"></p> <p><input type="submit" value="上传"></p> </form> </body> </html>
-
路由
path('test_upload', views.test_upload),
-
上传后,media目录下生成picture文件夹,上传的文件在内部
-
且数据库字段也保存路径
-
如果上传同一名称的图片,会自动添加后缀保存