Как переопределить глагол HTTP-запроса в GAE - PullRequest
1 голос
/ 01 ноября 2008

В контексте каркасного приложения Google App Engine Webapp:

Я хочу изменить глагол запроса в случае предоставляется параметр _method, например, если приходит запрос POST с параметром _method = PUT, мне нужно изменить запрос для вызова поставить метод обработчика. Это чтобы справиться со способом prototype.js работает с глаголами, такими как PUT и DELETE (обходной путь для IE). Вот мой первая попытка:

class MyRequestHandler(webapp.RequestHandler):
   def initialize(self, request, response):
       m = request.get('_method')
       if m:
           request.method = m.upper()
       webapp.RequestHandler.initialize(self, request, response)

Проблема в том, что по какой-то причине, когда перенаправление выполняется, self.request.params очищаются к тому времени, когда метод обработки (положить или delete) вызывается, даже если они были заполнены при инициализации называется. Кто-нибудь знает, почему это так? В качестве обходного пути я думал, что я может клонировать параметры во время инициализации (), но .copy () не работает, и я тоже не нашел способа сделать это.

Обновление: я получил очень полезный ответ от Арахнида. Решение, которое я выбрал, использует метакласс. Найдено ниже.

Ответы [ 2 ]

3 голосов
/ 01 ноября 2008

В любом случае вызов обработчика из инициализации не является правильным способом - если вы сделаете это, веб-приложение также вызовет исходный обработчик.

Вместо этого у вас есть несколько вариантов:

  • Вы можете создать подкласс webapp.WSGIApplication и переопределить вызов , чтобы выбрать метод на основе _method, когда он существует.
  • Вы можете проверить наличие _method при инициализации и, если он существует, соответствующим образом изменить переменную среды объекта REQUEST_METHOD. Это заставит класс WSGIApplication выполнить выбранный вами метод.

В любом случае, взгляните на google / appengine / ext / webapp / init .py в SDK, чтобы вы могли увидеть, как он работает.

2 голосов
/ 02 ноября 2008

Это паукообразный за ваш ответ. Указание мне на источник структуры было действительно полезно. В последний раз я смотрел, что источника там нет (был только .pyc), возможно, он изменился с новой версией SDK. Для моей ситуации я думаю, что переопределение WSGIApplication было бы правильным решением. Однако вместо этого я решил использовать метакласс, потому что он не требовал, чтобы я загружал (копировал) кучу кода платформы в мой код и затем модифицировал его. Это мое решение:

class RequestHandlerMetaclass(type):
    def __init__(cls, name, bases, dct):
        super(RequestHandlerMetaclass, cls).__init__(name, bases, dct)
        org_post = getattr(cls, 'post')
        def post(self, *params, **kws):
            verb = self.request.get('_method')
            if verb:
                verb = verb.upper()
                if verb ==  'DELETE':
                    self.delete(*params, **kws)
                elif verb == 'PUT':
                    self.put(*params, **kws)
            else:
                org_post(self, *params, **kws)
        setattr(cls, 'post', post)

class MyRequestHandler(webapp.RequestHandler):
    __metaclass__ = RequestHandlerMetaclass
...