Как переопределить глагол HTTP-запроса в GAE

1

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

Я хочу изменить глагол запроса запроса в случае a параметр _method предоставляется, например, если запрос POST приходит с параметром _method = PUT, мне нужно изменить запрос для вызова поместите метод обработчика. Это нужно, чтобы справиться с прототипом. 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 освобождаются к моменту обработки метода (put или delete) вызывается, даже если они были заполнены, когда инициализация была называется. Кто-нибудь знает, почему это? В качестве обходного пути я думал, что я может клонировать параметры при инициализации(), но .copy() не работает, и я тоже не нашел способ сделать это.

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

  • 0
    «По какой-то причине проблема заключается в том, что всякий раз, когда выполняется перенаправление, пустые self.request.params» - это self.request.params? или request.params?
  • 0
    Это был self.request.params, где self - Обработчик.
Теги:
rest
google-app-engine
metaclass

2 ответа

3

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

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

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

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

  • 0
    На самом деле, я пытаюсь второй метод, который вы описали. Мой код переназначает request.method на метод переопределения, но он не работает из-за некоторых странностей, которые я описал. Но вы сначала предложили метод, кажется, что-то хорошее, чтобы попробовать.
2

Thats Arachnid для вашего ответа. Направляя меня к источнику рамки, было действительно полезно. Последнее, что я посмотрел, источника там не было (был только .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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню