Armazenamento de imagens no Google DataStore usando o Flask (Python)
-
26-09-2019 - |
Pergunta
Estou usando o Flask no Google App Engine e estou desesperadamente procurando ajuda para resolver isso. A documentação do GAE fala sobre armazenar imagens no armazenamento de dados usando o BlobProperty, que deve ser feito algo assim:-
class MyPics(db.Model):
name=db.StringProperty()
pic=db.BlobProperty()
Agora a imagem deve ser armazenada no armazenamento de dados, fazendo isso:-
def storeimage():
pics=MyPics()
pics.name=request.form['name']
uploadedpic=request.files['file'] #where file is the fieldname in the form of the
file uploaded
pics.pic=db.Blob(uploadedpic)
pics.put()
redirect ... etc etc
Mas não consigo fazer isso. Como eu recebo DB.blob aceita uma string, mas dado um objeto FileStorage ... alguém pode me ajudar com isso. Além disso, se alguém pudesse me sugerir sobre como transmitir a imagem após o upload.
Solução
Ok, então foi assim que finalmente resolvi:-
@userreg.route('/mypics',methods=['GET','POST'])
def mypics():
if request.method=='POST':
mydata=MyPics()
mydata.name=request.form['myname']
file=request.files['file']
filedata=file.read()
if file:
mydata.pic=db.Blob(filedata)
mydata.put()
return redirect(url_for('home'))
return render_template('mypicform.html')
O acima armazena o arquivo como uma blob no armazenamento de dados e, em seguida, pode ser recuperado pelo Func abaixo:-
@userreg.route('/pic/<name>')
def getpic(name):
qu=db.Query(MyPics).filter('name =',name).get()
if qu.pic is None:
return "hello"
else:
mimetype = 'image/png'
return current_app.response_class(qu.pic,mimetype=mimetype,direct_passthrough=False)
Outras dicas
Você deve considerar usar o BlobStore
Para armazenar seus dados. Em vez de um db.Blob
você estaria usando blobstore.BlobReferenceProperty
: http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html#blobreferenceProperty
O upload e o download é bastante fácil, como mostrado aqui: http://code.google.com/appengine/docs/python/blobstore/overview.html#complete_sample_app
Eu tenho o seguinte modelo
class Picture(db.Model):
data = db.BlobProperty()
ext = db.StringProperty()
content_type = db.StringProperty()
e armazene -o usando o próximo código:
def create_picture():
if request.files['file']:
picture.data = request.files['file'].read()
picture.ext = request.files['file'].filename.rsplit('.', 1)[1]
picture.content_type = request.files['file'].content_type
picture.put()
flash(u'File uploaded', 'correct')
return redirect(url_for("edit_picture", id=picture.key()))
else:
return render_template('admin/pictures/new.html', title=u'Upload a picture', message=u'No picture selected')
Para renderizar uma miniatura, você pode usar o próximo código:
@frontend.route('/thumbnail/<id>/<width>x<height>.<ext>')
def thumbnail(id, width, height, ext):
key = db.Key(id)
picture = Picture.get(key)
img = images.Image(picture.data)
if width != '0':
w = int(width)
else:
w = img.width
if height != '0':
h = int(height)
else:
h = img.height
if img.height > h and h != 0:
w = (int(width) * img.width) / img.height;
if img.width > w:
h = (int(height) * img.height) / img.width;
thumb = images.resize(picture.data, width=w, height=h)
response = make_response(thumb)
response.headers['Content-Type'] = picture.content_type
return response