Python Werkzeug: изменить значения запроса (формы и аргументы) перед извлечением

Есть ли способ в Werkzeug редактировать значения запроса (формы и аргументы) перед его использованием?

Мне нужно закодировать значения запроса из utf8 в iso88591. Я создал функцию для обработки этого.

Я хотел бы использовать эту функцию для всех значений формы, чтобы избежать второй строки следующего:

lcl_var = request.form['post_arg']        
lcl_var = encode_utf8_to_iso88591(lcl_var)

Я не мог понять, что мне нужно из документов Werkzeug. Я предполагаю, что есть способ создать подкласс класса Request и переопределить один из его методов, который обрабатывает значения. Был бы очень признателен за конкретный пример того, как это реализовать хорошо.


person Kamil Sindi    schedule 03.11.2013    source источник


Ответы (1)


В документации Werkzeug существует ограниченный пример расширения синтаксического анализа запросов. Это немного похоронено, но это звук.

http://werkzeug.pocoo.org/docs/request_data/#how-to-extend-parsing

Поскольку Werkzeug — довольно низкоуровневый инструмент для HTTP, эту функцию также можно реализовать в вашем диспетчере запросов (при условии, что структура аналогична той, что описана в руководстве по Werkzeug, функции, которая применяет сопоставление URL-адресов к запросу).

ИЗМЕНИТЬ:

Похоже, что в документации Werkzeug лучший способ сделать это — обработать собственное свойство запроса вне потока. Было бы неплохо сделать так, чтобы сохранить неизменность свойства request.form:

def encode(value):
    #Your logic for the new dict vals
    return 'foo!'

class MixInRequest(Request):
    max_content_length = 1024 * 1024 * 4

    @cached_property
    def lcl_data(self):
        if self.method in ['POST','PUT','PATCH']:
            fields = dict([(key, encode(val)) for (key,val) in self.form.items()])
            return ImmutableMultiDict(fields)
        return None

Это устанавливает свойство запроса lcl_data (названное в честь вашей функции), которое будет анализировать при первом доступе и кэшировать для последующих вызовов. Он работает только для методов, которые будут заполнять request.form.

Полный пример здесь:

https://gist.github.com/DeaconDesperado/7292574

person DeaconDesperado    schedule 03.11.2013
comment
+1. Спасибо. Должен ли я в диспетчере сделать что-то вроде этого: request.form = parse_form_data(environ)[1]. Если да, то как мне переопределить parse_form_data? - person Kamil Sindi; 03.11.2013
comment
Вероятно, было бы лучше сохранить неизменность словаря запроса, поэтому лучший подход, вероятно, описан здесь: werkzeug.pocoo.org/docs/wrappers/ Это позволяет вам смешать собственный объект запроса и переопределить form_data_parser. Отредактирую ответ. - person DeaconDesperado; 03.11.2013
comment
Читая документы, кажется, что лучше всего установить пользовательское свойство с собственным представлением словаря прямо из потока. Вот рабочий пример, который я придумал, используя документы, извините за путаницу: gist.github.com/DeaconDesperado /7292574 - person DeaconDesperado; 03.11.2013
comment
Будет отредактировано со ссылкой после подтверждения работы. Я почти уверен, что это должно быть хорошо, но вы можете позволить ошибкам декодирования всплывать для отлова в приложении в зависимости от вашего варианта использования. - person DeaconDesperado; 03.11.2013
comment
Последний вопрос: для доступа к закодированным значениям мне нужно использовать что-то вроде: lcl_var = request.lcl_data['post_arg'] вместо request.form['post_arg']? Редактировать: Да, заставил это работать. Благодарен за вашу помощь! - person Kamil Sindi; 03.11.2013
comment
Можете ли вы привести свой пример в свой ответ? Я думаю, будет очень полезно для будущих посетителей этой страницы. - person Kamil Sindi; 03.11.2013
comment
Все готово. Включены пример и объяснение декоратора immutabledict и кэширования. - person DeaconDesperado; 03.11.2013