sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list sudo apt-get update sudo apt-get install mongodb-10gen若是你跟我同樣以爲讓經過上傳文件名的後綴判別用戶上傳的什麼文件徹底是捏着山藥當小黃瓜同樣欺騙本身, 那麼最好還準備個 Pillow 庫
pip install Pillow或 (更適合 Windows 用戶)
easy_install Pillow
import flask app = flask.Flask(__name__) app.debug = True @app.route('/upload', methods=['POST']) def upload(): f = flask.request.files['uploaded_file'] print f.read() return flask.redirect('/') @app.route('/') def index(): return ''' <!doctype html> <html> <body> <form action='/upload' method='post' enctype='multipart/form-data'> <input type='file' name='uploaded_file'> <input type='submit' value='Upload'> </form> ''' if __name__ == '__main__': app.run(port=7777)
若是不那麼講究的話, 最快速基本的存儲方案裏只須要 html
import pymongo import bson.binary from cStringIO import StringIO app = flask.Flask(__name__) app.debug = True db = pymongo.MongoClient('localhost', 27017).test def save_file(f): content = StringIO(f.read()) db.files.save(dict( content= bson.binary.Binary(content.getvalue()), )) @app.route('/upload', methods=['POST']) def upload(): f = flask.request.files['uploaded_file'] save_file(f) return flask.redirect('/')把內容塞進一個 bson.binary.Binary 對象, 再把它扔進 mongodb 就能夠了.
如今試試再上傳個什麼文件, 在 mongo shell 中經過 db.files.find() 就能看到了. python
不過 content 這個域幾乎肉眼沒法分辨出什麼東西, 即便是純文本文件, mongo 也會顯示爲 Base64 編碼. git
def save_file(f): content = StringIO(f.read()) c = dict(content=bson.binary.Binary(content.getvalue())) db.files.save(c) return c['_id'] @app.route('/f/<fid>') def serve_file(fid): f = db.files.find_one(bson.objectid.ObjectId(fid)) return f['content'] @app.route('/upload', methods=['POST']) def upload(): f = flask.request.files['uploaded_file'] fid = save_file(f) return flask.redirect( '/f/' + str(fid))
@app.route('/f/<fid>') def serve_file(fid): import bson.errors try: f = db.files.find_one(bson.objectid.ObjectId(fid)) if f is None: raise bson.errors.InvalidId() return f['content'] except bson.errors.InvalidId: flask.abort(404)
from PIL import Image allow_formats = set(['jpeg', 'png', 'gif']) def save_file(f): content = StringIO(f.read()) try: mime = Image.open(content).format.lower() if mime not in allow_formats: raise IOError() except IOError: flask.abort(400) c = dict(content=bson.binary.Binary(content.getvalue())) db.files.save(c) return c['_id']
def save_file(f): content = StringIO(f.read()) try: mime = Image.open(content).format.lower() if mime not in allow_formats: raise IOError() except IOError: flask.abort(400) c = dict(content=bson.binary.Binary(content.getvalue()), mime=mime) db.files.save(c) return c['_id'] @app.route('/f/<fid>') def serve_file(fid): try: f = db.files.find_one(bson.objectid.ObjectId(fid)) if f is None: raise bson.errors.InvalidId() return flask.Response(f['content'], mimetype='image/' + f['mime']) except bson.errors.InvalidId: flask.abort(404)
import datetime def save_file(f): content = StringIO(f.read()) try: mime = Image.open(content).format.lower() if mime not in allow_formats: raise IOError() except IOError: flask.abort(400) c = dict( content=bson.binary.Binary(content.getvalue()), mime=mime, time=datetime.datetime.utcnow(), ) db.files.save(c) return c['_id'] @app.route('/f/<fid>') def serve_file(fid): try: f = db.files.find_one(bson.objectid.ObjectId(fid)) if f is None: raise bson.errors.InvalidId() if flask.request.headers.get('If-Modified-Since') == f['time'].ctime(): return flask.Response(status=304) resp = flask.Response(f['content'], mimetype='image/' + f['mime']) resp.headers['Last-Modified'] = f['time'].ctime() return resp except bson.errors.InvalidId: flask.abort(404)
db.files.ensureIndex({sha1: 1}, {unique: true})若是你的庫中有多條記錄的話, MongoDB 會給報個錯. 這看起來很和諧無害的索引操做被告知數據庫中有重複的取值 null (實際上目前數據庫裏已有的條目根本沒有這個屬性). 與通常的 RDB 不一樣的是, MongoDB 規定 null, 或不存在的屬性值也是一種相同的屬性值, 因此這些幽靈屬性會致使唯一索引沒法創建.
import hashlib def save_file(f): content = StringIO(f.read()) try: mime = Image.open(content).format.lower() if mime not in allow_formats: raise IOError() except IOError: flask.abort(400) sha1 = hashlib.sha1(content.getvalue()).hexdigest() c = dict( content=bson.binary.Binary(content.getvalue()), mime=mime, time=datetime.datetime.utcnow(), sha1=sha1, ) try: db.files.save(c) except pymongo.errors.DuplicateKeyError: pass return c['_id']
import hashlib import datetime import flask import pymongo import bson.binary import bson.objectid import bson.errors from cStringIO import StringIO from PIL import Image app = flask.Flask(__name__) app.debug = True db = pymongo.MongoClient('localhost', 27017).test allow_formats = set(['jpeg', 'png', 'gif']) def save_file(f): content = StringIO(f.read()) try: mime = Image.open(content).format.lower() if mime not in allow_formats: raise IOError() except IOError: flask.abort(400) sha1 = hashlib.sha1(content.getvalue()).hexdigest() c = dict( content=bson.binary.Binary(content.getvalue()), mime=mime, time=datetime.datetime.utcnow(), sha1=sha1, ) try: db.files.save(c) except pymongo.errors.DuplicateKeyError: pass return sha1 @app.route('/f/<sha1>') def serve_file(sha1): try: f = db.files.find_one({'sha1': sha1}) if f is None: raise bson.errors.InvalidId() if flask.request.headers.get('If-Modified-Since') == f['time'].ctime(): return flask.Response(status=304) resp = flask.Response(f['content'], mimetype='image/' + f['mime']) resp.headers['Last-Modified'] = f['time'].ctime() return resp except bson.errors.InvalidId: flask.abort(404) @app.route('/upload', methods=['POST']) def upload(): f = flask.request.files['uploaded_file'] sha1 = save_file(f) return flask.redirect('/f/' + str(sha1)) @app.route('/') def index(): return ''' <!doctype html> <html> <body> <form action='/upload' method='post' enctype='multipart/form-data'> <input type='file' name='uploaded_file'> <input type='submit' value='Upload'> </form> ''' if __name__ == '__main__': app.run(port=7777)
[1] Developing RESTful Web APIs with Python, Flask and MongoDB github
http://www.slideshare.net/nicolaiarocci/developing-restful-web-apis-with-python-flask-and-mongodb web
https://github.com/nicolaiarocci/eve mongodb
[2] Flask Web Development —— 模板(上) shell
http://segmentfault.com/blog/young_ipython/1190000000749914 數據庫