在Pyramid中,如何在NewRequest事件处理器中检查视图是否为静态?

3 投票
2 回答
687 浏览
提问于 2025-04-17 04:50

我在Pyramid框架中有一个叫做NewRequest的事件处理器(订阅者),它的代码是这样的:

@subscriber(NewRequest)
def new_request_subscriber(event):
    request = event.request
    print('Opening DB conn')
    // Open the DB
    request.db = my_connect_to_db()
    request.add_finished_callback(close_db_connection)

不过,我发现即使请求是针对一个静态资源,数据库连接还是会被打开,这显然是没必要的。请问有没有办法在NewRequest处理器中检查请求是否是针对静态资源的?我试过把view_name和我的静态视图的名字进行比较,但在处理请求的这个早期阶段,view_name属性似乎是不可用的。

如果有人对此有有趣的想法,请告诉我!

2 个回答

1
def _connection(request):
    print "******Create connection***"
    #conn = request.registry.dbsession()
    conn = MySQLdb.connect("localhost", "DB_Login_Name", "DB_Password", "data_base_name")
    def cleanup(_):
        conn.close()
    request.add_finished_callback(cleanup)
    return conn

@subscriber(NewRequest)
def new_request_subscriber(event):
    print "new_request_subscriber"
    request = event.request
    request.set_property(_connection, "db", reify = True)

试试这个,我参考了下面这个网页 http://pyramid.readthedocs.org/en/1.3-branch/api/request.html 里面的“set_property”部分,对我有效。

3

一种简单粗暴的方法是把 request.path 这个变量和你的静态文件的根路径进行比较,比如用 request.path.startswith('/static/') 来判断。

我个人最喜欢的方法是给 request 对象添加一个叫 db 的属性,这个属性在你需要用的时候才会被计算出来。也就是说,虽然你把它加到了请求中,但在你真正访问它之前,它不会做任何事情。

import types

def get_db_connection(request):
    if not hasattr(request, '_db'):
        request._db = my_connect_to_db()
        request.add_finished_callback(close_db_connection)
    return request._db

def new_request_subscriber(event):
    request = event.request
    request.db = types.MethodType(get_db_connection, request)

在你后面的代码中,你可以通过 request.db() 来获取数据库连接。不过,遗憾的是,按照我所知,运行时不能直接给一个对象添加属性,所以你不能让 request.db 直接返回你想要的内容。不过,你可以通过一个食谱中的方法来实现这种效果,方法是你可以继承 Request 类,并通过 Pyramid 的 @reify 装饰器添加你自己的懒加载属性。

撰写回答