2010-03-03 87 views
2

我刚刚开始使用Google App Engine。目前,我的应用程序有两个页面:一个列出当前库存的所有库存,另一个列出给定项目的详细信息页面。我觉得我的编码可能更干。 (例如,我打电话打印页眉和页脚两次)。Google App Engine:我如何干这个基本的请求处理?

这是代码。我如何分析重复?

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() 

谢谢您的意见!

回答

6

这里是一个可能的重构:

class BaseHandler(webapp.RequestHandler): 

    def get(self, CSIN=None): 
     self.response.headers['Content-Type'] = 'text/html' 
     render('Views/header.html', self, {'title' : 'Store'}) 
     self.response.out.write('<h1>%s</h1> '% self.h1(CSIN)) 
     self.do_body(CSIN) 
     render('Views/footer.html', self, {}) 

class MainPage(BaseHandler): 

    def h1(self, CSIN): 
     return 'This is going to be the best Store app EVER!' 

    def do_body(self, CSIN): 
     items = Item.all().order('name').fetch(10) 
     render('Views/table.html', self, {'items': items}) 

class Detail(BaseHandler): 

    def h1(self, CSIN): 
     return 'DETAILS %s' % CSIN 

    def do_body(self, CSIN): 
     # no risk whatsoever of SQL injection here;-) 
     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}) 

这将使用模板方法设计模式。关于这个(和其他)DP(包括摘要记录和时间表,以及指向幻灯片PDF的指针)的介绍可以在here找到。

1

你可以做MainPageDetailMyRequestHandler子类,然后用钩来修改get行为:

class MyRequestHandler(webapp.RequestHandler): 
    def get(self,*args,**kws): 
     self.response.headers['Content-Type'] = 'text/html' 
     render('Views/header.html', self, {'title' : 'Store'}) 
     self.get_hook(self,*args,**kws) 
     render('Views/footer.html', self, {}) 

class MainPage(MyRequestHandler): 
    def get_hook(self): 
     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}) 

class Detail(MyRequestHandler): 
    def get_hook(self, CSIN): 
     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}) 
+0

方法调用中'*'的含义是什么? – 2010-03-03 03:21:22

+0

@Rosarch:'foo(* args)'是一种将任意数量的参数传递给函数的方法。见http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ – unutbu 2010-03-03 03:45:19

相关问题