AppEngine处理类似请求的优雅方式

时间:2011-08-29 16:21:01

标签: python google-app-engine web-applications

我正在制作一台服务器,可以让客户上传和下载不同型号的数据。是否有一些优雅的方式处理请求?

更准确地说,我不想做这样的事情,

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandlerForA),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandlerForB),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandlerForC),
])
run_wsgi_app(app)

因为我在处理程序中所做的事情都是一样的。例如,

class MyRequestHandlerForX(webapp.RequestHandler):
    def get(self, key=None):
        # return the instance with the designated key
    def post(self, key=None):
        # create/get the model instance
        # iterate through the property list of the instance and set the values

处理程序之间的唯一区别是为不同模型创建实例。网址相似,处理程序几乎相同。

我检查了this post关于重定向请求到其他处理程序的问题,我还读了一些通过类名创建实例的方法;但我认为它们都不好。

任何人都有一个很好的解决方案吗?

P.S。这是我在此的头一篇博文。如果有什么不合适请告诉我,谢谢。

3 个答案:

答案 0 :(得分:5)

如何执行此操作在很大程度上取决于请求处理程序中代码的详细信息。你可以这样做一个相当通用的:

class ModelHandler(webapp.RequestHandler):
  def get(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.get(key)
    # Do something with the instance - eg, print it out

  def post(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.create_from_request(self.request)

application = webapp.WSGIApplication([
    ('/foo/([^/]+)/([^/]+)', ModelHandler),
])

def main():
  run_wsgi_app(application)

if __name__ == '__main__':
  main()

这假定您在每个模型类上定义'create_from_request'类方法;你可能不希望这样做,因为它将模型定义与用于输入它们的表单紧密结合;相反,您可能希望将类型名称或类的映射存储到处理函数,或者通过反映类的属性来完全自动地执行表单和创建。既然你没有说明这样做是不确定的,那就很难具体了。

另请注意上面包含main()和其他样板文件;虽然它将以您粘贴它的方式工作,但添加main可以大大提高效率,因为它允许App Engine运行时避免在每次请求时评估您的模块。

答案 1 :(得分:0)

在您的情况下,我可能只是将所有内容都放在同一个网址路径上,并将详细信息放在GET参数中,例如/my_upload_and_download_url?model=modelA

您还可以使用具有大量网址路由支持的webapp2(http://webapp-improved.appspot.com/guide/app.html)。

答案 2 :(得分:0)

您可以解析网址路径并进行查找,如下所示:

import urlparse

model_lookup = {'ModelA':ModelA,'ModelB':ModelB, 'ModelC':ModelC}

class MyRequestHandler(webapp.RequestHandler):
    def get(self):
        url = urlparse.urlparse(self.request.uri)
        path_model = url.path.replace('/my_upload_and_download_url/','')
        model = model_lookup[path_model]
        ...

允许您为每个路径使用相同的类:

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandler),
])
run_wsgi_app(app)