2
我希望能夠以類似ASP.net MVC的方式路由我的請求。Google App Engine Python使用webapp2執行ASP.NET MVC路由
例如地址/ Home/Index/query-string /應將請求映射到HomeController並調用Index方法。
我做了這個實現,它的工作原理,但我想知道更好的方法來做到這一點。我剛剛開始使用Google App Engine和Python,並且我沒有太多的開發網站和Web應用程序的經驗。
這是我實現
YAML的文件:
- url: /.*
script: router.app
路由配置:
def StartUp():
sys.path.append(os.path.join(os.getcwd(), 'System'))
sys.path.append(os.path.join(os.getcwd(), 'Controllers'))
sys.path.append(os.path.join(os.getcwd(), 'Models'))
app.run()
app = webapp2.WSGIApplication([webapp2.Route('/', handler=Router, name='Default', defaults={'handler': 'home', 'method': 'index', 'query': ''}, build_only=False, handler_method='map'),
webapp2.Route('/<query>', handler=Router, name='DefaultC', defaults={'handler': 'home', 'method': 'index'}, build_only=False, handler_method='map'),
webapp2.Route('/<handler>/', handler=Router, name='DefaultCS', defaults={'method': 'index', 'query': ''}, build_only=False, handler_method='map'),
webapp2.Route('/<handler>/<query>', handler=Router, name='DefaultCA', defaults={'method': 'index'}, build_only=False, handler_method='map'),
webapp2.Route('/<handler>/<method>/', handler=Router, name='DefaultCAS', defaults={'query': ''}, build_only=False, handler_method='map'),
webapp2.Route('/<handler>/<method>/<query>', handler=Router, name='DefaultAll', build_only=False, handler_method='map'),
webapp2.Route('/<handler>/<method>/<query>/', handler=Router, name='DefaultAllS', build_only=False, handler_method='map')],
debug=True)
if __name__ == '__main__':
StartUp()
路由器
class Router(webapp2.RequestHandler):
def getControllerName(self, handler):
handler = handler.lower()
if(len(handler) == 0):
""" Error - redirect to error page """
return webapp2.redirect('/Error/')
if len(handler) == 1:
handler = handler[0].capitalize()
else:
handler = handler[0].capitalize() + handler[1:]
handler = handler + 'Controller'
return handler
def getActionName(self, method):
method = method.lower()
if(len(method) == 0):
""" Error - redirect to error page """
return webapp2.redirect('/Error/')
if len(method) == 1:
method = method[0].capitalize()
else:
method = method[0].capitalize() + method[1:]
requestType = self.request.method.lower()
requestType = requestType[0].capitalize() + requestType[1:]
return method
def loadController(self, controllerName):
""" Load the controller """
try:
fileName, pathName, description = imp.find_module(controllerName, None)
module = imp.load_module(controllerName, fileName, pathName, description)
# Add checking if class was found
controllerRef = getattr(module, controllerName)
return controllerRef
except ImportError, args:
logging.error('Error importing controller. ' + pprint.saferepr(args))
except Exception, args:
logging.error('Exception. ' + pprint.saferepr(args))
finally:
fileName.close()
def loadAction(self, controller, actionName):
try:
actionRef = getattr(controller, actionName)
except Exception, args:
logging.error('Exception. ' + pprint.saferepr(args))
return actionRef
def callController(self, controllerName, actionName, query):
try:
""" Load the controller """
controllerRef = self.loadController(controllerName)
controller = controllerRef(self, query)
actionRef = self.loadAction(controller, actionName)
actionRef()
except Exception, args:
logging.error('Exception. ' + pprint.saferepr(args))
def map(self, handler, method, query):
query = query.lower()
""" Create Names for Controller and Action"""
controllerName = self.getControllerName(handler)
actionName = self.getActionName(method)
self.callController(controllerName, actionName, query)
這裏是我的家控制器:
class HomeController(MVC.Controller):
def Index(self):
path = os.path.join(os.path.dirname('Views/Home/'), 'home.html')
self.Request.response.out.write(template.render(path, None))