操作
fobj = request.FILES.get("filename")
print(fobj.name) # 文件名称
print(fobj.size) # 文件大小
print(fobj.read()) # 读取全部(适用于小文件)
print(fobj.chunks()) # 按块来返回文件,通过for 循环进行迭代,可以将大文件按照块来写入服务器
print(fobj.multiple_chunks()) # 判断文件 是否大于2.5M,返回True/False
使用
# 1. 创建路由
path('upload/', views.handle_upload, name="upload"),# 文件上传
# 2. 编写html
<body>
<form action="{% url 'App03:upload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="photo"><br>
<input type="submit">
</form>
</body>
# 3. 视图函数接收
def handle_upload(request):
if request.method == "POST":
# 获取文件上传对象
fobj = request.FILES.get("photo") # 接收文件对象
path = os.path.join(settings.STATICFILES_DIRS[0], 'upload') # 创建文件保存地址
path = os.path.join(path, fobj.name) # 创建文件名
if fobj:
print(fobj.name, fobj.size) # 文件名称
# 文件读写
with open(path, 'wb') as target:
# 源文件是否大于2.5M
if fobj.multiple_chunks():
for data in fobj.chunks():
target.write(data)
else:
target.write(fobj.read())
return HttpResponse("文件上传成功")
return render(request, 'portra.html')
封装
# 1. settings.py设置文件上传路径
MDEIA_ROOT=os.path.join(BASE_DIR,'static/upload')
# 2. util.py
# 文件上传封装
import os
from datetime import datetime
from random import randint
class FileUpload:
def __init__(self, file, exts=('png', 'jpg', 'jpeg'), size=1024 * 1024, is_randomname=False):
"""
:param file: 文件上传对象
:param exts: 文件类型
:param size: 文件大小 默认1M
:param is_randomname: 是否随机文件名,默认否
"""
self.file = file
self.exts = exts
self.size = size
self.is_randomname = is_randomname
# 文件上传
def upload(self, dest):
"""
:param data: 文件上传的目标目录
:return:
"""
# 1. 判断文件类型是否匹配
if not self.check_key():
return -1
# 2. 判断文件大小,是否符合要求
if not self.check_size():
return -2
# 3. 如果随机文件名,要生成随机文件名
if self.is_randomname:
self.file_name = self.random_filename()
else:
self.file_name = self.file.name
# 4. 拼接目标文件路径
path = os.path.join(dest, self.file_name)
# 5. 保存文件
self.write_file(path)
return 1
def check_key(self):
ext = os.path.splitext(self.file.name) # splitext: 分割文件名和 .后缀名
if len(ext) > 1:
ext = ext[1].lstrip(".")
if ext in self.exts:
return True
return False
def check_size(self):
if self.size < 0:
return False
# 如果文件大小小于给定大小,返回True,否则返回False
return self.file.size <= self.size
def random_filename(self):
filename = datetime.now().strftime("%Y%m%d%H%M%S") + str(randint(1, 10000))
ext = os.path.splitext(self.file.name)
# 获取文件后缀
ext = ext[1] if len(ext) > 1 else " "
filename += ext
return filename
def write_file(self, path):
with open(path, 'wb') as fp:
if self.file.multiple_chunks():
for chunk in self.file.chunks():
fp.write(chunk)
else:
fp.write(self.file.read())
# 3. 调用
def handle_upload(request):
if request.method == "POST":
# 获取文件上传对象
fobj = request.FILES.get("photo")
# 使用自定义文件上传类
path = settings.MDEIA_ROOT
fp = FileUpload(fobj)
if fp.upload(path):
return HttpResponse("文件上传成功")
return render(request, 'portra.html')