如何解决Django上传图片转base64时出现的InMemoryUploadedFile类型错误
报错原因
TypeError: expected str, bytes or os.PathLike object, not InMemoryUploadedFile报错的核心是:request.FILES['propic']拿到的是Django封装的InMemoryUploadedFile内存上传文件对象,你直接把这个对象传给了open()函数,但open()仅接受文件路径、字节、类路径对象作为入参,无法识别这个Django自定义的上传文件类。
实际上Django的上传文件对象本身就支持直接读取字节内容,完全不需要调用open()走读取本地文件的逻辑。
修复后的视图代码
你需要修改两处逻辑:一是去掉open()调用直接读取文件内容,二是存数据库时传入转换完成的base64字符串,而非原上传文件对象:
import base64 from django.shortcuts import render from django.http import HttpResponseRedirect from django.urls import reverse from django.contrib.auth import login from django.db import IntegrityError def signup(request): if request.method == "POST": username = request.POST["username"] fullname = request.POST["fullname"] password = request.POST["password"] email = request.POST["email"] area = request.POST["area"] school = request.POST["school"] propic = request.FILES["propic"] # 直接读取上传文件对象的字节内容 binary_file_data = propic.read() base64_encoded_data = base64.b64encode(binary_file_data) # 可选:补充图片类型前缀,方便前端直接用该字符串渲染图片,不需要可以删除前缀拼接逻辑 base64_message = f"data:{propic.content_type};base64,{base64_encoded_data.decode('utf-8')}" try: # propic字段传入转换好的base64字符串,不要传原上传文件对象 user = User.objects.create_user( username=username, email=email, password=password, area=area, school=school, propic=base64_message ) user.save() except IntegrityError: return render(request, "alumnas/register.html", { 'message':"Username taken" }) login(request, user) return HttpResponseRedirect(reverse("index")) else: return render(request, "alumnas/register.html")
注意事项
- 请确认你扩展的User模型中
propic字段为TextField类型:base64编码后的图片字符串长度很长,CharField的最大长度限制无法满足存储需求。 - 可根据需求增加上传校验逻辑,避免非法文件提交:
# 仅允许图片格式上传 ALLOWED_IMG_TYPES = ["image/jpeg", "image/png", "image/gif"] if propic.content_type not in ALLOWED_IMG_TYPES: return render(request, "alumnas/register.html", {"message": "仅支持上传JPG、PNG、GIF格式的图片"}) # 限制图片大小不超过2M if propic.size > 2 * 1024 * 1024: return render(request, "alumnas/register.html", {"message": "图片大小不能超过2M"}) - 非特殊需求不建议将base64图片直接存储在数据库中,会占用大量存储空间、降低查询效率,更推荐将图片存到本地静态目录或对象存储服务,数据库仅存储图片的访问路径。
内容的提问来源于stack exchange,提问作者Rasax Zero
相关产品推荐
相关产品推荐

