【问题标题】:GAE: How can a handler return a webapp2.Response when using sessions and overriding `dispatch`?GAE:处理程序如何在使用会话和覆盖`dispatch`时返回webapp2.Response?
【发布时间】:2013-03-24 04:53:32
【问题描述】:

我调整了this sample code,以便让 webapp2 会话在 Google App Engine 上运行。

我需要做什么才能从一个继承自覆盖dispatch 方法的 BaseHandler 的处理程序中获得return webapp2.Response objects

这是我想要编写的处理程序类型的演示:

import webapp2
import logging

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)


class HomeHandler(BaseHandler):
  def get(self):
    logging.debug('In homehandler')
    response = webapp2.Response()
    response.write('Foo')
    return response

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'some-secret-key',
}


app = webapp2.WSGIApplication([
    ('/test', HomeHandler),
], debug=True, config=config)


这段代码显然不起作用,因为 BaseHandler 总是用self 调用调度。我查看了webapp2.RequestHandler 的代码,但它严重地让我无法修改我的 BaseHandler(或者可能设置自定义调度程序),以便我可以简单地从继承处理程序返回响应对象。

奇怪的是,分配self.response = copy.deepcopy(response) 的快捷方式也不起作用。

【问题讨论】:

  • 您忘记了代码中的两个重要部分,它们是您改编的示例的一部分。 1) 具有缓存属性的会话方法 2) 在基本处理程序中使用会话,使用 self.session...
  • 我知道 - 在我的实际应用程序中,我的会话工作正常(使用您提到的方法),它们不是问题。这只是理解调度和处理程序子类化问题所需的基本示例。
  • 为什么要返回响应对象?你想用它做什么?
  • 我正在调整一个已经从请求数据构造响应对象的库 (github.com/StartTheShift/pyoauth2)。我不介意将返回的响应对象复制到self.response 的开销,但鉴于 deepcopy 分配不起作用...... - 单独复制每个响应属性似乎相当丑陋且容易出错。
  • 也许设置 self.response=response ?我以前没有尝试过,但它可能会起作用......

标签: python google-app-engine session webapp2


【解决方案1】:

您在一种方法中混合了两种响应。使用任一

return webapp2.Response('Foo')

self.response.write('Foo')

...不是两者都有。

【讨论】:

  • 感谢您的回复。不过,我不完全明白这与我的问题有什么关系。 (我认为我如何构建响应体并不重要(这只是一个例子,请注意))。我的问题是如何在继承类仍然能够显式返回简单响应对象的同时启用会话(而不是隐式调用to self.response)。我的临时解决方案是明确地执行 BaseHandler 在调度中为每个调用所做的会话咕噜工作。我更喜欢更精简的解决方案。
  • 在您的代码中,看起来您的 dispatch() 方法正在做正确的事情(您的“更精简的解决方案”)。只需将您的 get() 方法更改为使用 self.response 而不是创建新的 webapp2.Response()。
  • 哦,我明白你在说什么。你是对的。但是,我正在调整一个库,该库输出现成的响应对象,包括状态代码、正文、标题。现在在使用该库的应用程序中...... - 我宁愿简单地返回那些预先打包的响应,而不是将它们的内容复制到self.response。特别是因为self.response = copy.deepcopy(response) 因我也无法理解的原因而不起作用。如果有帮助,请参阅上面的我的 cmets。感谢您的帮助。
【解决方案2】:

我查看了 webapp2.RequestHandler 并注意到返回的值只是向上传递了堆栈。

一个对我有用的解决方案是在从处理程序返回时使用返回的响应,或者在没有返回任何内容时使用 self.response。

class BaseHandler(webapp2.RequestHandler):
    def dispatch(self):
        # Get a session store for this request.
        self.session_store = sessions.get_store(request=self.request)

        response = None
        try:
            # Dispatch the request.
            response = webapp2.RequestHandler.dispatch(self)
            return response
        finally:
            # Save all sessions.
            if response is None:
                response = self.response
            self.session_store.save_sessions(response)

在玩游戏时,我注意到当处理程序中引发异常时,我存储为安全 cookie 的会话没有得到更新。

【讨论】:

    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2012-02-06
    • 2017-01-13
    • 2013-10-20
    • 2014-10-03
    • 2020-06-28
    • 2016-06-05
    • 2012-08-15
    相关资源
    最近更新 更多