24-文件上传

操作

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')
posted @ 2023-03-28 18:33  测试圈的彭于晏  阅读(31)  评论(0)    收藏  举报