【问题标题】:AppEngine elegant way to handle similar requestsAppEngine 处理类似请求的优雅方式
【发布时间】:2011-08-29 16:21:00
【问题描述】:

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

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

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

处理程序之间的唯一区别是为不同的模型创建实例。 url 是一样的,handler 也差不多。

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

谁有好的解决方案?

附言这是我在此的头一篇博文。如果有什么不妥的地方请告诉我,谢谢。

【问题讨论】:

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


    【解决方案1】:

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

    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 运行时避免在每次请求时评估您的模块。

    【讨论】:

      【解决方案2】:

      在你的情况下,我可能只是让所有内容都点击相同的 url 路径,并将细节放在 GET 参数中,例如 /my_upload_and_download_url?model=modelA

      你也可以使用 webapp2 (http://webapp-improved.appspot.com/guide/app.html),它有一堆 url 路由支持。

      【讨论】:

      • 这并不能真正解决问题。 Webapp 已经完全有能力做到这一点。
      • 啊,它也是。我完全忘记了这一点。
      【解决方案3】:

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

      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)
      

      【讨论】:

      • Webapp 内置了用于提取部分路径的机制 - 真的没有必要使用 urlparse 进入那里并以硬(和脆弱)的方式进行。
      • 哇,关于 db.class_for_kind 以及如何使用路径组件作为参数的 TIL - 谢谢!
      猜你喜欢
      • 2016-07-12
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2013-01-04
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多