如何在 GAE 中覆盖 HTTP 请求动词
Posted
技术标签:
【中文标题】如何在 GAE 中覆盖 HTTP 请求动词【英文标题】:How to override HTTP request verb in GAE 【发布时间】:2010-09-20 06:55:09 【问题描述】:在 Google App Engine Webapp 框架应用程序的上下文中:
我想改变一个请求的请求动词 参数 _method 被提供,例如如果一个 POST 请求进来 使用参数 _method=PUT,我需要更改请求以调用 处理程序的 put 方法。这是为了应付prototype.js的方式 适用于 PUT 和 DELETE 等动词(IE 的解决方法)。这是我的 第一次尝试:
MyRequestHandler 类(webapp.RequestHandler): 定义初始化(自我,请求,响应): m = request.get('_method') 如果米: request.method = m.upper() webapp.RequestHandler.initialize(自我,请求,响应)问题是,由于某种原因,每当重定向完成时, self.request.params 在处理方法(put 或 delete) 被调用,即使它们在初始化时被填充 叫。任何人都知道这是为什么?作为一种解决方法,我认为我 可以在 initialize() 时间克隆参数,但是 .copy() 不起作用, 我也没有找到办法。
更新:我收到了来自 Arachnid 的非常有用的回复。我最终得到的解决方案使用了元类。它位于下面。
【问题讨论】:
“问题是,由于某种原因,每当重定向完成时,self.request.params 被清空” - 是 self.request.params 吗?或 request.params? 是 self.request.params,其中 self 是 Handler。 【参考方案1】:从初始化调用处理程序无论如何都不是正确的方法 - 如果你这样做,webapp 也会调用原始处理程序。
相反,您有几个选择:
您可以继承 webapp.WSGIApplication 并覆盖 call 以选择基于 _method 的方法(如果存在)。 您可以在initialize中检查_method是否存在,如果存在,则相应地修改请求对象的“REQUEST_METHOD”环境变量。这将导致 WSGIApplication 类执行您选择的方法。无论哪种方式,请查看 SDK 中的 google/appengine/ext/webapp/init.py,以便了解它是如何工作的。
【讨论】:
实际上,我正在尝试您描述的第二种方法。我的代码将 request.method 重新分配给 override 方法,但由于我描述的一些怪异,它不起作用。但是你第一个建议的方法似乎很好尝试。【参考方案2】:那是 Arachnid 的回应。向我指出框架的来源真的很有帮助。最后我查看了源不存在(只有 .pyc),也许它随着 SDK 的新版本而改变。对于我的情况,我认为重写 WSGIApplication 是正确的做法。但是,我选择使用元类,因为它不需要我将一堆框架代码cargo-cult(复制)到我的代码中然后修改它。这是我的解决方案:
类 RequestHandlerMetaclass(类型): def __init__(cls, name, bases, dct): 超级(RequestHandlerMetaclass,cls).__init__(名称,基地,dct) org_post = getattr(cls, 'post') def post(self, *params, **kws): 动词 = self.request.get('_method') 如果动词: 动词 = verb.upper() 如果动词 == '删除': self.delete(*params, **kws) elif 动词 == 'PUT': self.put(*params, **kws) 别的: org_post(self, *params, **kws) setattr(cls,“发布”,发布) MyRequestHandler 类(webapp.RequestHandler): __metaclass__ = RequestHandlerMetaclass【讨论】:
以上是关于如何在 GAE 中覆盖 HTTP 请求动词的主要内容,如果未能解决你的问题,请参考以下文章