2017-01-08 7 views
0

Должен быть лучший и более Pythonic способ сделать это. Я создал небольшое приложение GAE, которое демонстрирует мою проблему (и незнание). Здесь вы вводите свое имя на странице входа. Затем приложение приветствует вас и увеличивает число нажатий. Отлично работает - пока кто-то еще не использует приложение одновременно, и в этот момент один пользователь наследует имя другого.Избегайте глобалов Python в Google App/Cloud Engine

Это потому, что имя хранится в a_state, глобальном (singleton) объекте, объявленном внизу? Если да, то как я могу убедиться, что все пользователи сохраняют свои собственные имена? Заранее спасибо!

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

Примечание: В реальном приложении, я использую ndb для хранения информации, которые должны быть распределены между всеми пользователями (успешно!). Моя проблема связана с этой более эфемерной, специфичной для пользователя информацией.

Это правильное решение, чтобы укусить пулю и хранить даже этот материал в хранилище данных?

ответ

0

Из моих старых дней php я должен был знать, что термин, который я искал, - СЕССИЯ. Hooray - webapp2 имеет сессии тоже. Вот полный рабочий код; это может помочь кому-то, кто пытается получить минимальную работу.

Ключом является определение нового обработчика запросов, BaseHandler. Вам также нужно будет установить конфигурацию. См. 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()