Tornado - Python全局变量

1 投票
2 回答
2138 浏览
提问于 2025-04-17 21:44

我正在尝试将Tornado和SqlAlchemy结合使用,我需要在插入或更新操作时,从RequestHandler(tornado)将当前用户传递给模型(SqlAlchemy)。但是我不想直接把这个值传给模型,比如:

#### RequestHandler POST method...
user = Session.query(User).get(1)
user.name = "bla, bla, bla..."
user.updated_by = self.current_user # don't use...
session.commit()

我在一个__ init__.py文件中使用了一个全局变量,在RequestHandler中设置当前用户的值,然后在SqlAlchemy的更新前事件中获取这个值。

这样做的目的是为了知道哪个用户是创建者和更新者。

为什么我不想像之前的例子那样直接把当前用户传给模型呢?因为这将是一个供其他开发者使用的工具,我想让他们使用起来更方便。此外,他们可能会忘记这一点,而这其实是很重要的。

这样做是个好主意吗?或者有没有其他更好的方法呢?

2 个回答

0

当前用户在每个处理器和模板中都是可以用的。你如何确定、验证和设置当前用户,完全取决于你自己。

基本上,你只需要创建一个新的类,继承自 tornado.web.RequestHandler,然后在你自己的基础处理器中重写 get_current_user 方法。

以下是来自tornado文档的引用:

tornado 用户认证

用户认证 当前已认证的用户可以在每个请求处理器中通过 self.current_user 访问,在每个模板中通过 current_user 访问。默认情况下,current_user 是 None。

要在你的应用中实现用户认证,你需要在请求处理器中重写 get_current_user() 方法,以根据例如 cookie 的值来确定当前用户。这里有一个例子,用户只需输入一个昵称就可以登录应用,这个昵称会保存在 cookie 中。

你可以在官方的 tornado 博客示例中看到一个完整的工作示例。

0

如果你同时处理多个请求,你的解决方案可能会出现问题。Tornado是一个异步的网页框架,这意味着另一个请求可能会覆盖你的全局变量,把用户设置成其他人。为了避免这种情况,最好把与请求相关的数据存储在self里,这样Tornado会确保这些数据不会被其他同时进行的请求修改。

一个可能适合你的解决方案是把你的工具放在基本处理器里,或者创建一个装饰器。具体的建议有点复杂,如果你想要更好的替代方案,请在你的问题中提供更多信息。

撰写回答