Reputation: 111
I'm trying to make it so that when someone uploads a picture(successfully), its redirected to a permalink with the uploaded image showing. Here is what I've tried so far.
import webapp2
import os
import re
import jinja2
from google.appengine.api import images
from google.appengine.ext import db
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env= jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir), autoescape = True, extensions=['jinja2.ext.autoescape'])
PAGE_RE = r'(/(?:[a-zA-Z0-9_-]+/?)*)'
def render_str(template, **params):
t = jinja_env.get_template(template)
return t.render(params)
class BaseHandler(webapp2.RequestHandler):
def render(self, template, **kw):
self.response.out.write(render_str(template, **kw))
def render_str(self, template, **params):
params['user'] = self.user
return render_str(template, **params)
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
class ImageModel(db.Model):
patient_id = db.IntegerProperty(required = True)
patient_image = db.BlobProperty(required = True)
class NewImageHandler(BaseHandler):
def get(self):
self.render('newimage.html')
def post(self):
patient_id = int(self.request.get('patient_id'))
patient_image = self.request.POST.get('patient_image').file.read()
img = str(images.Image(patient_image))
i = ImageModel(patient_id = patient_id, patient_image = db.Blob(img))
i.put()
self.redirect('imageanalysis/%s' % str(i.key().id()) )
class ImageAnalysisHandler(BaseHandler):
def get(self, image_id):
key = db.Key.from_path('ImageModel', int(image_id))
imageD= db.get(key)
self.render('imageAnalysis.html', imageD = imageD, image_key = imageD.key())
app = webapp2.WSGIApplication([
('/newimage', NewImageHandler),
('/imageanalysis/([0-9]+)', ImageAnalysisHandler),
], debug=True)
Here is what my form for the 'newimage.html' looks like:
<form method = "post" enctype="multipart/form-data" action = "/newimage">
<input type="text"name="patient_id" value = {{patient_id}} >
<input type="file" name="patient_image">
<input type="submit" style="width: 100px" 1000px value="Submit">
Here is HTML for the 'imageanalysis
<div>{{imageD.patient_id}}</div>
<div>{{imageD.key()}}
<img src='/{{image_key}}'>
</div>
It is able to render the page and display the patient_id, but it can't display the image. Can someone explain to me how I can serve images dynamically. I've tried many of the things in the documentation, but it just doesn't work.
Upvotes: 1
Views: 1388
Reputation: 123
I recommend using the blobstore to store the images. This will free you of any size limitations that are imposed upon you by the blobproperty and you will get the serving features for free.
It does however require that your store your images a bit differently. Here's an example of how you can achieve that:
import webapp2
from google.appengine.api import files, images
class ImageAPIHandler(webapp2.RequestHandler):
def post(self):
image = self.request.POST.get('image')
blob = files.blobstore.create(
mime_type='image/jpeg',
_blobinfo_uploaded_filename=image.filename,
)
with files.open(blob, 'a') as f:
f.write(image.file.read())
files.finalize(blob)
blob_key = files.blobstore.get_blob_key(blob)
self.response.redirect(images.get_serving_url(blob_key))
Note, that this is an untested snipped sourced from various codebits in a project I'm running live. There might be some bugs in it, but it should give you the general idea of how to use the blobstore.
Good luck.
Upvotes: 2
Reputation: 15143
You're confusing blobs in the datastore with the blobstore.
You're currently storing blobs in your datastore. You're expecting an image to be served when you access the url given by:
<img src='/{{image_key}}'>
However, you don't seem to have a handler that serves up the actual image data. If you're storing data in the datstore, there's no free handlers. You'll have to write your own HTTP handler that will fetch the image data blob from the datastore, format it properly and return an HTTP response with the image data.
An alternative is to use the blobstore which can store and serve data. You'll have to adjust your handlers accordingly to use the blobstore. After a blob has been uploaded, you can get a url from the blobstore from which your images can directly be served.
Upvotes: 2
Reputation: 464
Check out ServeHandler in the example in the documentation. You probably want to be using send_blob.
https://developers.google.com/appengine/docs/python/blobstore/overview#Complete_Sample_App
Upvotes: 0