-->

Tornado - Python global variable

2019-06-03 15:58发布

问题:

I'm trying to use Tornado with SqlAlchemy, I need to pass the current user from RequestHandler (tornado) to models (SqlAlchemy) in the insert or update action. But I don't want to pass the value directly to the model, example:

#### 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()

I'm using a global variable, in a __ init__.py file, and set the current user value in the RequestHandler and after, get the value, in before update event with SqlAlchemy.

The idea is to know what user is the creator and updater. Why I don't want pass the current user directly to model like the before example ?, because this will be a tool for other developers, and I'm trying to make comfortable for them, also, they can forget about it and it is important.

Is this a good idea, or maybe is there other better way ?

回答1:

Your solution will have issues if you're handling more than one request at a time. Tornado is an async web framework so another request might overwrite your global var and set the user to someone else. It's good practice to store request depending data on self, tornado will make sure that data is altered by other simultaneous requests.

A solution that might work for you is to add your tool in the basic handler or create a decorator. It's tricky to sugest more details, please include more info in your question if you would like to get better alternatives.



回答2:

The current user is available in every handler (and template). How you determine, authenticate and set the current user is up to you.

Basically just subclass tornado.web.RequestHandlerand override the get_current_user method in your new/own BaseHandler.

Here the quote from the tornado docs:

tornado User authentication

User authentication The currently authenticated user is available in every request handler as self.current_user, and in every template as current_user. By default, current_user is None.

To implement user authentication in your application, you need to override the get_current_user() method in your request handlers to determine the current user based on, e.g., the value of a cookie. Here is an example that lets users log into the application simply by specifying a nickname, which is then saved in a cookie.

You can see a fully working example in the official tornado blog demo