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)) 

回答

0

使用這種方法我找不到更好的方法。

這樣做的另一種方法是在類和方法上使用裝飾器來指定路徑(不知道實現這種功能有多容易)。

@RouteFor('/SomePath') 
    class HomeController(MVC.Controller): 
     @RouteFor('/SomePath/Index') 
     def Index(self): 
       path = os.path.join(os.path.dirname('Views/Home/'), 'home.html') 
       self.Request.response.out.write(template.render(path, None)) 
相關問題