如何将JSON字符串内容正确存入Django的FileField字段
问题原因
Django的FileField字段无法直接接收Python原生文件对象作为值,要求必须传入django.core.files.File类或其子类的实例,这类实例内置了Django ORM保存时需要的_committed等属性,你之前直接赋值open()生成的原生文件对象,就会触发属性不存在的报错。
另外你注释里f.clean(data['data'])报错的原因是forms.FileField的clean方法要求接收上传文件类实例,你传入的是字符串类型的文件内容,自然找不到name属性。
解决方案
推荐直接使用ContentFile子类从字符串内容直接生成符合要求的文件对象,不需要额外写入本地磁盘,效率更高:
from django.core.files.base import ContentFile import json import logging logger = logging.getLogger(__name__) def uploadaction2(request): data = json.loads(request.body) file_content = data['data'] # 生成符合Django要求的文件对象,第二个参数是保存的文件名,可自定义 file_obj = ContentFile(file_content, name="自定义文件名.txt") # 赋值给用户的FileField request.user.file = file_obj request.user.save()
如果你确实需要先将内容写入本地磁盘再保存到FileField,需要用Django的File类包装原生文件对象:
from django.core.files import File import json def uploadaction2(request): data = json.loads(request.body) file_content = data['data'] with open('newfile', 'w') as f: f.write(file_content) # 用Django的File类包装打开的文件,指定文件名 with open('newfile', 'r') as f: file_obj = File(f, name="自定义文件名.txt") request.user.file = file_obj request.user.save()
注意事项
- 如果你的文件内容是二进制格式(比如图片、压缩包),需要将
ContentFile的内容改为bytes类型,文件打开方式改为wb/rb即可 name参数的值会作为文件保存在FileField指定的upload_to目录下的文件名,可根据业务需求自定义
内容的提问来源于stack exchange,提问作者rivercity
相关产品推荐
相关产品推荐

