在我的Flask项目中,我试图让文件上传与MongoDB一起使用。从this upload tutorial获取灵感我设法上传文件并将其存储在文件系统中。使用these mongoengine docs我现在也想将它存储在MongoDB中。如何将上传的文件保存在Flask的mongoDB中?
我的当前文档的定义如下:
class UserDocument(mongoDb.Document):
created = mongoDb.DateTimeField(default=datetime.utcnow, required=True)
filename = mongoDb.StringField()
_file = mongoDb.FileField()
和我上传并存储与以下视图中的文件:
@app.route('/upload', methods=['GET', 'POST'])
def mytickets():
if request.method == 'POST':
file = request.files['file']
if file and isAllowedFile(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # This works!
userDoc = UserDocument()
userDoc.filename = filename
userDoc._file.put(file, content_type=file.content_type)
userDoc.save()
else:
return 'We don\'t allow this file extension.'
return render_template('upload.html')
该文件被在文件系统中创建的,因此有一份文件。在命令行中我证实存在MongoDB的一个文件,但似乎_file的内容为空:
>>> UserDocument.objects.count()
1
>>> d = UserDocument.objects.first()
>>> d._file.read()
''
我想这可能是因为你不能显示在命令行上的图像数据,所以我想知道如何通过Flask再次显示文档。为此,我做了一个简单的瓶视图来显示一个文件:
@app.route('/show')
def showSomething():
doc = UserDocument.objects.first()
return doc._file.read()
,这并不会返回任何东西,或者是因为该文件永远不会被写入到MongoDB的,或者是因为我的showSomething是不正确的,或两者兼而有之。
有人会知道我在做什么错吗?欢迎所有提示!
[编辑] 我试着读取文件的内容并将其添加到文档中。由于read()现在输出一些十六进制的东西,这使我进一步(见下文)。问题是,我不明白如何从文件中读取它并从Flask文件上传中获取它是不同的。最后;有没有一种简单的方法来使用Flask在浏览器中显示输出?
>>> from app.documents import UserDocument
>>> UserDocument.objects.count()
0
>>> f = open('/Users/kramer65/repos/tc/app/static/uploads/IMG_7599.JPG', 'r') # I'm on MacOSX, so 'rb' doesn't exist
>>> userdoc = UserDocument()
>>> userdoc.filename = 'blabla.jpg'
>>> userdoc._file.put(f, content_type='image/jpeg')
>>> userdoc.save()
<UserDocument: UserDocument object>
>>> UserDocument.objects.count()
1
>>> d = UserDocument.objects.first()
>>> d._file.read()
'\xff\xd8\xff\xe1%\xfeExif\x00\x00II*\x00\x08\x00\x00\x00\t\x00\x0f etc. etc.'
>>> d._file.read()
'' # Why oh why is it the second time suddenly an empty string?!
您是否尝试打开刚刚以'rb'模式保存的文件并将其提供给put方法? – Dragu 2014-09-25 11:37:46
@Dragu - 感谢您的提示。我尝试了你的建议,并将结果添加到上面的问题中。这似乎做了一些事情,但read()方法仍然输出一个空字符串。还有什么想法? – kramer65 2014-09-25 12:14:21
@Dragu - 我在我的问题中编辑了我的编辑,因为我现在从'.read()'得到了一些十六进制输出。奇怪的是,它不会在第二次调用'.read()'时输出任何东西(见上文)。还有什么想法吗? :S – kramer65 2014-09-25 13:17:09