【问题标题】:Pyramid: extend query string for every URL constructed by route_urlPyramid:为 route_url 构造的每个 URL 扩展查询字符串
【发布时间】:2013-02-22 16:50:17
【问题描述】:

我正在使用 Webframework Pyramid 和 URL Dispatch,我在其中定义了很多类似的路由

config.add_route('login', '/login')
config.add_route('logout', '/logout')

现在我想在查询字符串中添加一些内容,例如由

构建的 URL
request.route_url('login')

其实

/login?foo=bar

这应该基于项目来完成,以避免编写

request.route_url('login', _query={'foo': 'bar'})

每次我想构建一个 URL。

执行此操作的正确位置是什么?我应该以某种方式从 pyramid.request 类继承并覆盖 route_url 方法吗?有我可以使用的事件或钩子吗?

【问题讨论】:

  • request.route_url('login', _query={'foo': 'bar'}) 有什么问题?根据您的描述,我无法提出问题所在。你想在拨打request.route_url('login')时得到/login?foo=bar吗?
  • 不,我想在 every 调用 route_url 中获取 /login?foo=bar,而不在每次调用 route_url 时插入 kwarg _query。当然,这只是出于源代码美学的原因。
  • 就像我说的。拨打request.route_url('login') 时,您想获得/login?foo=bar。还是您的意思是在没有任何参数的情况下调用request.route_url() 时要获取/login?foo=bar?在这两种情况下,我都会从pyramid.request.Request 继承,覆盖route_url() 方法并在启动时调用config.set_request_factory
  • request.route_url('login') 应该产生/login?foo=bar 等等(对于每条路线)。我将按照您的建议进行操作,并从 Request 继承,并在完成后将此解决方案作为答案发布。

标签: python web-applications url-routing pyramid


【解决方案1】:

您可以定义一个预生成器并将其分配给您的路线。

def add_query_pregen(request, elements, kwargs):
    query = kwargs.setdefault('_query', {})
    query.setdefault('foo', 'bar')
    return elements, kwargs

def add_route_with_query(*args, **kwargs):
    kwargs['pregenerator'] = add_query_pregen
    config.add_route(*args, **kwargs)

add_route_with_query('login', '/login')
add_route_with_query('logout', '/logout')

基本上,只要您调用 request.route_url 等,就会调用预生成器,并传递元素和 kwargs,允许您在实际生成 url 之前对它们进行变异。

【讨论】:

  • 我还不知道pregenrators。您的建议是它使代码的可重用性降低,因为我需要将__init__ 中对add_route 的每次调用更改为add_route_with_query。我最好只向项目中添加一些文件或只更改一个文件。因此,我将尝试从他的评论中实施@floqqi 的建议并将其作为答案发布。
  • 它实际上是更多可重用的,因为您的系统中仍然可以有没有预生成器的路由。您可能认为您现在不需要这样做,但根据我的经验,这通常是短视的。子类化和覆盖 Pyramid 生成 url 的一种方式是全局操作,你最好确定你是认真的。
【解决方案2】:

根据本站的讨论,我实现了以下解决方案:

from pyramid.request import Request as OldRequest

class Request(OldRequest):
    def route_url(self, route_name, *elements, **kw):
        qs = kw.get('_query', {})
        if 'hid' in qs: raise Exception('hid exists in query string')
        qs['hid'] = 1337
        kw['_query'] = qs
        return self.route_without_hid(route_name, *elements, **kw)

    def route_url_without_hid(self, route_name, *elements, **kw):
        return super(Request, self).route_url(route_name, *elements, **kw)

它还可以构建没有隐藏的 URL。

【讨论】:

  • 我还有一个问题:目前我在__init__ 函数中使用config = Configurator(request_factory=Request)。有没有一种装饰风格的方法?
猜你喜欢
  • 1970-01-01
  • 2011-09-05
  • 2013-07-21
  • 1970-01-01
  • 2020-11-14
  • 2015-07-16
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多