werkzeug 将 url 映射到视图(通过端点)

发布于 2024-08-12 01:02:09 字数 674 浏览 7 评论 0原文

开始使用 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 时,它可能会变得很糟糕...

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

Starting using werkzeug, i try to map urls (from a file urls.py) to views (from a folder views and then in different files to manage differents kinds of view), my folder organisation looks like that :

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

my urls.py files looks like that:

from werkzeug.routing import Map, Rule  

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

and obviously i got that piece in the views/places.py file :

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

Most of werkzeug examples show the utilisation of the decorator expose to attach urls to views. It's practical for an app with 5 or 6 urls but can become a hell when you got more...

Is there a simple way to map the urls directly to the views???
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春有你 2024-08-19 01:02:09

这是一个简化的示例:

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)

Here is a simplified example:

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)
囚我心虐我身 2024-08-19 01:02:09
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),
])

端点可以是任何东西,包括函数,所以你可以跳过 Denis 示例中的 import magic

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 can be anything, including function, so you can just skip import magic from Denis's example

幸福%小乖 2024-08-19 01:02:09

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

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)

这样您可以保留视图命名抽象层并避免使用“字符串导入”产生奇怪的魔法。

I'm not sure if it is preferred way to tackle this problem (I haven't found any similar example in werkzeug repo and I'm still only playing with this lib) but it is also possible to simply subclass Rule:

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)

In that way you can preserve layer of view naming abstraction and avoid strange magic with 'string importing'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文