2011-08-29 38 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以及如何使用路徑組件作爲參數 - 謝謝! –