我目前正在Django中为Mailchimp中的一个webhook创建一个回调URL,Mailchimp将以application/x-www-form-urlencoded
的形式发送一个带有urlencoded数据的POST请求。
我遇到的问题是返回的数据包含嵌套数据,这个urlencoded字符串中的一些数据看起来像它定义的嵌套JSON,我认为这是非标准的(尽管我可能错了)。
例如,当用户更改其名称时,Mailchimp会发送一个POST请求,如下所示:type=profile&fired_at=2021-05-25+18%3A03%3A23&data%5Bid%5D=abcd1234&data%5Bemail%5D=test%40domain.com&data%5Bemail_type%5D=html&data%5Bip_opt%5D=0.0.0.0&data%5Bweb_id%5D=1234&data%5Bmerges%5D%5BEMAIL%5D=test%40domain.com&data%5Bmerges%5D%5BFNAME%5D=first_name&data%5Bmerges%5D%5BLNAME%5D=last_name&data%5Blist_id%5D=5678
使用Django的request.POST
,数据被解码为:
{
'type': 'profile',
'fired_at': '2021-05-25 18:03:23',
'data[id]': 'abcd1234',
'data[email]': 'test@domain.com',
'data[email_type]': 'html',
'data[ip_opt]': '0.0.0.0',
'data[web_id]': '1234',
'data[merges][EMAIL]': 'test@domain.com',
'data[merges][FNAME]': 'first_name',
'data[merges][LNAME]': 'last_name',
'data[list_id]': '5678'
}
这在实践中看起来非常难看,因为要从request.POST
访问用户的名字,我们必须执行以下操作
request.POST.get("data['merges']['FNAME']", None)
数据显然是为了看起来像
{
'type': 'profile',
'fired_at': '2021-05-25 18:03:23',
'data': {
'id': 'abcd1234',
'email': 'test@domain.com',
'email_type': 'html',
'ip_opt': '0.0.0.0',
'web_id': '1234',
'merges':{
'email': 'test@domain.com',
'fname': 'first_name',
'lname': 'last_name',
},
'list_id': '5678'
},
}
并且可以像
data = request.POST.get('data', None)
first_name = data['merges']['FNAME']
我已经寻找了一种Django/Python特有的方法来将这种嵌套的URL编码的数据解码成更适合在Python中使用的格式,但是没有找到任何东西。Python的urllib
库提供了诸如urllib.parse.parse_qs()之类的方法来解码urlencoded字符串,但是这些方法不处理这种嵌套类型的数据。
有没有办法用Django/Python正确地解码这个嵌套的urlencoded数据?
1条答案
按热度按时间5f0d552i1#
没有标准的库或Django实用函数来实现这一点。
我们可以这样实现
convert_form_dict_to_json_dict
:1.将
json_dict
初始化为空dict{}
。1.对于每个
form_key
,使用示例'data[merges][EMAIL]'
,1.使用正则表达式获得
nested_keys
,即('data', 'merges', 'EMAIL')
。1.确定
last_nesting_level
,即从嵌套级别(0, 1, 2)
确定2
。1.将
current_dict
初始化为json_dict
。1.对于每个
nesting_level, current_key
,即0, 'data'
、1, 'merges'
、2, 'EMAIL'
,1.如果它在
last_nesting_level
之前,则使用current_key
获取下一个current_dict
。1.否则,将
current_key
的current_dict
条目设置为value
。1.返回
json_dict
。用法: