I'm just getting started with Google App Engine. Currently, my app has two pages: one lists all the inventory currently in stock, and the other is a detail page for a given item. I feel that my coding could be much more DRY. (I'm making all the calls to print headers and footers twice, for instance.)
Here is the code. How can I factor out the repetition?
from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp.util import run_wsgi_app
import os
from google.appengine.ext.webapp import template
def render(filename, main, template_values):
path = os.path.join(os.path.dirname(__file__), filename)
main.response.out.write(template.render(path, template_values))
class Item(db.Model):
CSIN = db.IntegerProperty()
name = db.StringProperty()
price = db.IntegerProperty() # OK that it's ints?
quantity = db.IntegerProperty()
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
render('Views/header.html', self, {'title' : 'Store'})
self.response.out.write('<h1>This is going to be the best Store app EVER!</h1>')
items = Item.all().order('name').fetch(10)
render('Views/table.html', self, {'items': items})
render('Views/footer.html', self, {})
class Detail(webapp.RequestHandler):
def get(self, CSIN):
self.response.headers['Content-Type'] = 'text/html'
render('Views/header.html', self, {'title' : 'Store'})
self.response.out.write('<h1>DETAILS %s</h1>' % CSIN)
# SQL injection risk here, or is that taken care of by the pattern?
item = db.GqlQuery("SELECT * FROM Item WHERE CSIN = :1", int(CSIN)).get()
if (item):
render('Views/item_detail.html', self, {'item': item})
else:
render('Views/item_not_found.html', self, {'CSIN': CSIN})
render('Views/footer.html', self, {})
application = webapp.WSGIApplication([('/detail/(\d+)', Detail),
('/.*', MainPage)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
Thank you for your comments!