Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle delete in Google App Engine (Python)

I'm a newbie programmer and new to Google App Engine and webapp2 etc. So this may be a very basic question.

I am creating an application to store images into BlobStore. My model stores description, blob_key, image url and date.

I am able to save everything, so that bit is okay.

But now I want to create a delete button which will not only delete an item from the datastore, but also delete the image saved in the blobstore.

I have created a DeleteHandler, and in the html I have a form, passing the key for the item I want to delete. In the DeleteHandler, I am using the posted key to delete the item from the datastore. I am also trying to use the key to use it delete the image saved in the blobstore.

So far I'm getting a 404 on the delete form post, and even if I get past that, I'm not sure if my DeleteHandler is correct to handle the functionality I am looking for.

Any help would be much appreciated..

Main.py:

import os
import urllib
import webapp2
from google.appengine.ext.webapp import template
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.api import images
#Models
from google.appengine.ext import db

class ImageItem(db.Model):
    description = db.StringProperty(required=True)
    img_url = db.StringProperty()
    blob_key = blobstore.BlobReferenceProperty()
    when = db.DateTimeProperty(auto_now_add=True)


#Handlers (Views)
class MainHandler(webapp2.RequestHandler):
  def get(self):
    upload_url = blobstore.create_upload_url('/upload')
    imgs = db.GqlQuery(
        'SELECT * FROM ImageItem '
        'ORDER BY when DESC')
    imgs_dict = {'imgs': imgs}
    self.response.out.write( template.render( 'main.html',locals() ) )

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    f = self.get_uploads('file')[0]  # 'file' is file upload field in the form
    img =ImageItem(description=self.request.get('description'))
    img.blob_key = f.key()
    img.img_url = images.get_serving_url( f.key() )
    img.put()
    self.redirect('/')

class DeleteHandler(webapp2.RequestHandler):
    def post(self):
        key = self.request.get('k')
        item = db.get(key)
        images.delete( item.blob_key )
        item.delete()
        self.response.out.write(key)

#URL Routing happens here
app = webapp2.WSGIApplication([('/', MainHandler),
                               ('/upload', UploadHandler),
                               ('/delete', DeleteHandler)],
                              debug=True)

Main.html:

<form action="{{upload_url}}" method="POST" enctype="multipart/form-data">
            <p>
                <label for="file">Upload File</label>
                <input type="file" name="file" id="file">
            </p>
            <p>
                <label for="description">Description</label>
                <input type="text" id="description" name="description">
            </p>
            <input type="submit" name="submit" value="Submit"> 
    </form>

    <ul>
        {% for i in imgs %}
        <li>
            <img src="{{i.img_url}}=s400-c" alt="">
            {{i.description }}
            </li>

        <li>{{i.when }}</li>
        <li>
            <form action="/delete" method="POST"  enctype="multipart/form-data">
                <input type="text" name="k" value="{{i.key}}" />
                <input type="submit" value="delete">
            </form>

        </li>
        {% endfor %}
    </ul>
like image 975
user791793 Avatar asked Nov 17 '12 15:11

user791793


2 Answers

The deletes are close. Once you have a key, you can delete entities by calling db.delete(key).
For your example, this would be something like this:

class DeleteHandler(webapp2.RequestHandler):
    def post(self):
        key = self.request.get('k')
        item = db.get(key)
        blobstore.delete([item.blob_key])
        db.delete(item)
        self.response.out.write(key)


Your url handling in main.py is good, so it's not obvious to me why you're getting a 404. You could double-check your app.yaml file to make sure all urls are passed to main.py.
Here's a sample app.yaml handlers url section:

handlers
- url: /.*
    script: main.app


like image 120
Eric Olson Avatar answered Nov 12 '22 19:11

Eric Olson


Got it to work. Thanks Eric, yours was real close. I needed to use blob_key.key().

Final code is following:

class DelHandler(webapp2.RequestHandler):
  def post(self):
    key = self.request.get('k')
    item = db.get(key)
    n = item.blob_key.key() 
    blobstore.delete(n)
    item.delete()
    self.redirect('/')
like image 42
user791793 Avatar answered Nov 12 '22 20:11

user791793