There must be a better and more Pythonic way to do this. I have created a small GAE app that demonstrates my problem (and ignorance). Here you enter your name on an entry page. The app then greets you and increments a number with every click. Works great -- until someone else uses the app at the same time, at which point one user inherits the other's name.
Is this because the name is stored in a_state
, a global (singleton) object declared at the bottom? If so, how can I make sure all users keep their own names? Thanks in advance!
import webapp2
class AState:
my_name = "Foo"
a_number = 42
class GetName(webapp2.RequestHandler):
def post(self):
the_state.my_name = self.request.get('the_name')
self.redirect('/main')
def get(self):
self.response.write("""
<html><body><form action="/" method="post">
Type your name <input type="text" name="the_name">
<input type="submit" value="Continue">
</form></body></html>
""")
class Main(webapp2.RequestHandler):
def get(self):
the_state.a_number += 1
self.response.write("""
<html><body><form action="/main" method="get">
Hello, %s! The number is %d.
<input type="submit" value="Keep going">
</form></body></html>
""" % (the_state.my_name, the_state.a_number))
app = webapp2.WSGIApplication([
('/', GetName),
('/main', Main)
], debug=True)
the_state = AState()
Note: In the real app, I'm using ndb
to store (successfully!) information that should be shared among all users. My problem is with this more ephemeral, user-specific info.
So is the right solution to bite the bullet and store even this stuff in the datastore?
From my old php days, I should have known that the term I was looking for was SESSION. Hooray -- webapp2
has sessions too. Here is complete working code; it may help someone trying to get a minimal program working.
The key is to define a new handler for requests, BaseHandler
. You will also have to set a configuration. See this webapp2 documentation .
import webapp2
from webapp2_extras import sessions
class BaseHandler(webapp2.RequestHandler):
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
@webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
class GetName(BaseHandler): # NB: see how we're now inheriting from BaseHandler?
def post(self):
self.session['my_name'] = self.request.get('the_name')
self.session['a_number'] = 42 # NB: setting a session variable
self.redirect('/main')
def get(self):
self.response.write("""
<html><body><form action="/" method="post">
Type your name <input type="text" name="the_name">
<input type="submit" value="Continue">
</form></body></html>
""")
class Main(BaseHandler):
def get(self):
t_num = self.session.get('a_number') # NB: retrieving a session variable
t_num += 1
self.session['a_number'] = t_num
self.response.write("""
<html><body><form action="/main" method="get">
Hello, %s! The number is %d. <input type="submit" value="Keep going">
</form></body></html>
""" % (self.session.get('my_name'), t_num))
config = {}
config['webapp2_extras.sessions'] = {
'secret_key': 'H81%6_(^&k2&)!' # or some other miscellaneous string
}
app = webapp2.WSGIApplication([
('/', GetName),
('/main', Main)
], debug=True, config=config) # NB the config gets added
def main():
app.run()
if __name__ == '__main__':
main()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.