【问题标题】:werkzeug mapping urls to views (via endpoint)werkzeug 将 url 映射到视图(通过端点)
【发布时间】:2009-11-25 10:37:24
【问题描述】:

开始使用 werkzeug,我尝试将 url(从文件 urls.py)映射到视图(从文件夹视图,然后在不同的文件中管理不同类型的视图),我的文件夹组织如下所示:

myapp/
   application.py
   urls.py
   views/
      __init__.py
      common.py
      places.py
      ...

我的 urls.py 文件如下所示:

from werkzeug.routing import Map, Rule  

url_map = Map([  
Rule('/places', endpoint='places.overview')  
])  

显然我在 views/places.py 文件中找到了那部分:

def overview(request):
    mycode...
    render_template('places.html', extra...)

大多数 werkzeug 示例显示了使用装饰器暴露来将 url 附加到视图。对于一个有 5 或 6 个 url 的应用来说这很实用,但是当你有更多的时候可能会变成地狱......

有没有一种简单的方法可以将 url 直接映射到视图???
谢谢。

【问题讨论】:

    标签: python werkzeug


    【解决方案1】:

    这是一个简化的例子:

    import views
    
    def app(environ, start_response):
        urls = url_map.bind_to_environ(environ)
        request = Request(environ)
        endpoint, params = urls.match()
        names = endpoint.split('.')
        view = views
        for name in names:
            if not hasattr(view, name):
                __import__(view.__name__, None, None, [name])
            view = getattr(view, name)
        try:
            response = view(request)
        except werkzeug.exceptions.HTTPException, exc:
            response = exc
        return response(environ, start_response)
    

    【讨论】:

      【解决方案2】:
      import letters # our views module
      
      url_map = Map([
          Rule('/letters', endpoint=letters.index),
          Rule('/letters/<int:item_id>', endpoint=letters.item),
          Rule('/letters/<string:section_slug>', endpoint=letters.index),
          Rule('/letters/<string:section_slug>/<int:item_id>',
               endpoint=letters.item),
      ])
      

      endpoint 可以是任何东西,包括函数,因此您可以跳过 Denis 示例中的 import magic

      【讨论】:

      • 是的,这可能很有用,但是您需要导入 urls.py 文件和模板中的所有视图以使用例如“url_for”。谢谢
      【解决方案3】:

      我不确定它是否是解决这个问题的首选方法(我在 werkzeug 存储库中没有找到任何类似的例子,我仍然只使用这个库)但也可以简单地继承规则:

      class CoolRule(Rule):
      
          def __init__(self, view, *args, **kwargs):
              self.view = view
              super(CoolRule, self).__init__(*args, **kwargs)
      
          def empty(self):
              """We need this method if we want to use 
                 Submounts or Subdomain factories
              """
              defaults = dict(self.defaults) if self.defaults else None
              return CoolRule(self.view, self.rule, defaults, self.subdomain,
                              self.methods, self.build_only, self.endpoint, 
                              self.strict_slashes, self.redirect_to,
                              self.alias, self.host)
      
      
      _url_map = Map([
          CoolRule(user.views.login, '/login', endpoint='user-login'),
          CoolRule(user.views.logout, '/logout', endpoint='user-logout'),
      ])
      
      def dispatch(request):
          urls = _url_map.bind_to_environ(request.environ)
          rule, arguments = urls.match(return_rule=True)
          return rule.view(request, **arguments)
      

      通过这种方式,您可以保留视图命名抽象层并避免使用“字符串导入”的奇怪魔法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-24
        • 1970-01-01
        相关资源
        最近更新 更多