2011-08-29 40 views
2

我做了一个服务器,可以让客户上传和下载不同型号的数据。有没有一些优雅的方式来处理请求?AppEngine优雅的方式来处理类似的请求

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

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.这是我在此的头一篇博文。如果有什么不妥请告诉我,谢谢。

回答

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

+0

谢谢,它太棒了! –

0

在你的情况下,我可能只是让所有的东西都碰到相同的url路径,并把参数放在GET之内,比如/my_upload_and_download_url?model=modelA

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

+0

这并不能真正解决问题。 Webapp已经完全可以做到这一点。 –

+0

啊,它也是。我完全忘记了这一点。 –

0

你可以解析出的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) 
+0

Webapp内置了用于提取部分路径的机制 - 实际上并不需要使用urlparse去实现,而是采用困难(和脆弱)的方式。 –

+0

哇,TIL关于db.class_for_kind以及如何使用路径组件作为参数 - 谢谢! –