9

我正在使用 Python 实现服务器端过滤以服务 KendoUI 的 Grid 组件。

我面临的问题是它默认生成的 AJAX 调用似乎与 Flask 的内置 URL 解析器和 Python 的urlparse模块都不兼容。

这是我遇到问题的查询字符串类型的人为示例:a=b&c=d&foo[bar]=baz&foo[baz]=qis&foo[qis]=bar

这是我想要的结果:

{
    'a': 'b',
    'c': 'd',
    'foo': {
        'bar': 'baz',
        'baz': 'qis',
        'qis': bar'
    }
}

不幸的是request.args,如果将其传递给 Flask 端点,您会得到以下结果:

{
    'a': 'b',
    'c': 'd',
    'foo[bar]': 'baz'
    'foo[baz]': 'qis'
    'foo[qis]': 'bar'
}

更糟糕的是,在实践中,该结构可能有好几层深。将列过滤foo为仅值等于的行的基本调用'bar'将产生以下结果:

{
    'filter[logic]': 'and',
    'filter[filters][0][value]': 'bar',
    'filter[filters][0][field]': 'foo',
    'filter[filters][0][operator]': 'eq'
}

我检查了 RFC,它要求查询字符串只包含“非分层”数据。虽然我相信它指的是 URI 所代表的对象,但在我能找到的规范中没有对这种类型的数据结构的规定。

我开始编写一个函数,它接受一个参数字典并返回它们所代表的嵌套结构,但我很快意识到这是一个微妙的问题,而且肯定有人以前遇到过这个问题。

是否有人知道将以我想要的方式解析这些参数的模块,或者我可能忽略的解析它们的优雅方式?

4

3 回答 3

8

我只是写了一个小函数来做到这一点:

from collections import defaultdict
import re
params = {
    'a': 'b',
    'c': 'd',
    'foo[bar]': 'element1',
    'foo[baz]': 'element2',
    'foo[qis]': 'element3',
    'foo[borfarglan][bofgl]': 'element4',
    'foo[borfarglan][bafgl]': 'element5',
}

def split(string, brackets_on_first_result = False):
    matches = re.split("[\[\]]+", string)
    matches.remove('')
    return matches

def mr_parse(params):
    results = {}
    for key in params:
        if '[' in key:
            key_list = split(key)
            d = results
            for partial_key in key_list[:-1]:
                if partial_key not in d:
                    d[partial_key] = dict()
                d = d[partial_key]
            d[key_list[-1]] = params[key]
        else:
            results[key] = params[key]
    return results
print mr_parse(params)

这应该适用于任何嵌套级别。

于 2013-01-14T17:55:00.973 回答
3

前段时间我发现了这个项目:https ://github.com/bernii/querystring-parser

它专门针对做你想做的事。

然而,在 PHP 世界之外,GET(和 POST)参数的行为不同。就像它们通常使用多值字典来实现一样。因此,更好的想法可能是适应这一点或找到一种与这两个世界兼容的方法。

或者,您可以真正在请求正文 (POST) 中使用 JSON 序列化数据,并将访问的资源视为控制器(执行某些操作的资源,在这种情况下,在您将一些数据传递给它之后搜索某事)。

于 2013-01-14T18:35:35.567 回答
0

您也可以在 GET 请求中发送正文。如果您只需要发送一些分层数据,则可能只是客户端上的 json.dumps(data) 和服务器上的 json.loads(data)。

您可以在此处参考 httplib 文档中的此类做法:http: //docs.python.org/2/library/httplib.html#httplib.HTTPConnection.request

于 2013-01-14T17:16:31.700 回答