django 自定义路径上传照片 文件 返回前端文件流

为什么要指定以上传照片呢 以为传统的使用models表 sttings配置 路由配置 这样的路径就写死了

# 实现 #文件重命名 通过用户user_id创造对应的用户文件夹 使用PIL包保存照片 获取旧照片信息 更新照片数据 删除旧照片

    def put(self,request):
        '''修改用户头像'''
        # 获取上传的文件
        file = request.FILES.get("avatar",None)
        user_id = request.data.get('user_id')
        if file: #修改头像
            file_operate = FileOperate()
            # 命名文件
            filename = file_operate.rename(file.name)
            # 文件不存在创建文件
            file_operate.mkdir(user_id)

            try:
                # 保存图片
                img = Image.open(file)
                path = "./static/%s/%s" % (user_id,filename)
                img.save(r'%s'% path)  # 路径(相对)
            except:
                return JsonResponse(code=400, result={"message":"照片格式错误"})
            user = User.objects.filter(id=user_id).first()
            oldavatar = user.avatar
            # 数据库更改avatar
            user.avatar = filename
            user.save()
            # 删除旧照片
            file_operate.remove(user_id,oldavatar)
            return JsonResponse(code=200, result={"message":"头像修改成功"})

获取照片路径进行访问 #通过user_id 找到 static下对应的文件夹 访问照片名称 这里合理的应该是将文件名写入mysql 通过mysql 读取对应的照片

    def get(self,request):
        '''获取照片'''
        user_id = request.GET.get("user_id")
        filename = request.GET.get("filename")
        if not (user_id and filename):
            return JsonResponse(400, error_info="缺少必要参数")
        imagepath = "./static/%s/%s" % (user_id,filename)
        try:
            image_data = open(imagepath, "rb").read()
        except:
            return JsonResponse(200,error_info="不存在")
        return HttpResponse(image_data, content_type="image/png")

代码里面的内容我给你解释

FileOperate 是我写了一个文件的操作类 #用到了文件重命名 #文件夹不存在就创建 #删除文件 三个方法  JsonResponse 是我设置的返回值 用到了PIL包保存照片 有一个好处它可以判断是否是照片 

#这是文件操作类  save方法可以保存文件 直接把接收的文件传给他就行

# 创建文件操作类
class FileOperate:
    def __init__(self, file_dir="./static/"):

        self.file_dir = file_dir
    
    #文件重命名
    def rename(self, filename):
        # 获取文件路径文件名
        ext = os.path.splitext(filename)[-1]
        # 生产新文件名
        newfile = uuid.uuid4().hex + ext
        return newfile

    # 创建文件夹
    def mkdir(self, id):
        if not os.path.exists(self.file_dir + '/' + str(id)):
            os.mkdir(self.file_dir + '/' + str(id))

    # 删除文件
    def remove(self, id, filename):
        try:
            os.remove(self.file_dir + '/' + str(id) + '/' + filename)
        except:
            pass

    # 保存文件    
    def save(self,files):
        filename =  os.path.join(self.file_dir, files.name)
        with open(filename, 'wb') as f:
            for file in files.chunks():
                f.write(file)

    #读取文件
    def read_file(self,file_name):
        with open(file_name, "rb") as f:
            while True:
                c = f.read()
                if c:
                    yield c
                else:
                    break

这是 JsonResponse 你也可以用正常的Response 这都是没问题的

def JsonResponse(code: int, result: dict or list = None, error_info: str = "", status=200):
    """
    格式化返回
    """
    return Response(
        data={
            "code": code,
            "result": result if result is not None else {},
            "error_info": error_info,
        },
        status=status,
    )

这就是完成的路径

返回前端文件流 FileOperate类上边有 可以用 Postman 测试下 Send 下拉选择 Send and Download

    def get(self,request):
        
        file_operate = FileOperate()
        file_name = "computer_room.xlsx" 
        file_path = "./asset_manage/asset_template/computer_room.xlsx"
        response = StreamingHttpResponse(file_operate.read_file(file_path))
        response["Content-Type"] = "application/octet-stream"
        response["Content-Disposition"] = 'attachment; filename={0}'.format(file_name)
        response["Access-Control-Expose-Headers"] = "Content-Disposition"  # 为了使前端获取到Content-Disposition属性

        return response


版权声明:本文为weixin_56482316原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。