为什么建议使用pyramid.threadlocal.get_current_request?

时间:2012-09-07 18:53:18

标签: python pyramid

我的假设是正确的请求对象不是保证的结果,但我想确切地知道为什么它是不明智的,并且推荐的方法是从视图函数向下传递请求对象。

2 个答案:

答案 0 :(得分:6)

请求对象进入视图后,建议您不要原样"原样"任何非特定于网络的代码。处理数据库等的任何代码都不应该与金字塔的请求概念相关联。这种模式在Pyramid中更容易理解,因为它避免了全局请求对象。

请求对象包含了有关为什么调用视图的所有内容,并且使得与该对象相关的代码超过必要的代码将导致您在管道中进一步编写函数,这些函数可能会过多地执行#34;。< / p>

答案 1 :(得分:2)

我同意迈克尔·梅里克尔所说的话,但我有很多传统的Pylons应用程序已被移植,并且需要以许多不同的代码访问请求对象。

为了实现这一目标,几乎所有“面向Web”的功能都将请求作为他们的第一个参数。我几乎都说,因为有些人没有。这不是因为我不想要它们,而是因为我还没有将它们移植到这个范例中。有一些模块未与网络耦合,并以其他方式命名和构造。 [像文本处理一样的东西,我的项目使用非基于金字塔的应用程序]但是任何可能与请求一起作用或交互的东西 - 它都有作为第一个arg 的请求是否或不是我现在需要它

我的代码不标准的原因是我不听迈克尔这样的人,我仍然使用get_current_request ...直到我开始遇到问题并理解他们警告我的内容 - 所以我我一直在零碎地修理东西。

让我远离使用get_current_request()的两个主要因素是:

  1. 当我希望传入请求时:单元测试。我来自Pylons,我们有全局gc个对象。我真的很喜欢他们的便利。然后我尝试编写单元测试,这是一场彻头彻尾的噩梦。你经常不得不重写代码来堵塞请求对象。

  2. 当我想要请求时:并非所有内容都与网络相关联。在某个项目中,我有几个守护进程通过Twisted框架运行定期工作。他们处理大量相同的数据并分享一些任务。我也有迁移脚本,crontabs等。如果这些需要与Pyramid交互,我必须在重复的项目中保持相同的功能。

  3. 所以我的方法是创建我的lib的一个部分,它与金字塔紧密耦合,需要一个请求对象,以及我的lib的另一部分,它与金字塔完全无关。

    我的金字塔请求对象中有很多有用的东西 - 标题,会话,数据库连接等。这是一个非常方便的地方来存储“请求”导向的数据。每当有非金字塔系统可能使用的任务时,我就会这样实现:

    • 真正的函数位于lib.universal中,并期望args如'dbSession'
    • 如果需要,我还会创建一个位于lib.pyramid中的包装器函数,并且只包含通用 - 传递来自'request'的相关内容

    他是一个简单而又愚蠢的例子:

    lib.universal

    from ... import model
    def get_user_by_id( dbSession , id , permissionsObject ):
        if not validate_permissions( permissionsObject ):
             raise ValueError('Not allowed')
        return dbSession.query( model.User ).filter( id=id ).first()
    

    lib.pyramid

    from .. import universal
    def get_user_by_id( request , id ):
        return universal.get_user_by_id( request.dbSession , id , request.permissionsObject     )