>>> raw_post_data = request.raw_post_data
>>> print raw_post_data
{"group":{"groupId":"2", "groupName":"GroupName"}, "members":{"1":{"firstName":"fName","lastName":"LName","address":"address"},"1": {"firstName":"f_Name","lastName":"L_Name","address":"_address"}}}
>>> create_request = json.loads(raw_post_data)
>>> print create_request
{u'group': {u'groupName': u'GroupName', u'groupId': u'2'}, u'members': {u'1': {u'lastName': u'L_Name', u'firstName': u'f_Name', u'address': u'_address'}}}
正如您所见,当我使用json.dumps()
有没有办法在python中将它作为异常捕获,说在客户端请求中找到重复的密钥?
答案 0 :(得分:27)
The rfc 4627 for application/json
media type建议使用唯一键,但不明确禁止它们:
对象中的名称应该是唯一的。
来自rfc 2119:
应该这个词,或形容词“推荐”,意味着有 在特定情况下可能存在有效理由忽略 特定项目,但必须理解全部含义和 在选择不同的课程之前仔细权衡。
import json
def dict_raise_on_duplicates(ordered_pairs):
"""Reject duplicate keys."""
d = {}
for k, v in ordered_pairs:
if k in d:
raise ValueError("duplicate key: %r" % (k,))
else:
d[k] = v
return d
json.loads(raw_post_data, object_pairs_hook=dict_raise_on_duplicates)
# -> ValueError: duplicate key: u'1'
答案 1 :(得分:2)
这是answer by jfs的linter-fixed和type-annotated版本。解决了各种短路问题。 Python 3.6+也使用f-strings进行了现代化改造。
import json
from typing import Any, Dict, Hashable, List, Tuple
def check_for_duplicate_keys(ordered_pairs: List[Tuple[Hashable, Any]]) -> Dict:
"""Raise ValueError if a duplicate key exists in provided ordered list of pairs, otherwise return a dict."""
dict_out: Dict = {}
for key, val in ordered_pairs:
if key in dict_out:
raise ValueError(f'Duplicate key: {key}')
else:
dict_out[key] = val
return dict_out
json.loads('{"x": 1, "x": 2}', object_pairs_hook=check_for_duplicate_keys)
答案 2 :(得分:1)
或者,如果您想要捕获所有重复的键(每个级别),您可以使用collections.Counter
from collections import Counter
class KeyWatcher(dict):
def __init__(self, *args):
duplicates = [d for d,i in Counter([pair[0] for pair in args[0]]).items() if i > 0]
if duplicates:
raise KeyError("Can't add duplicate keys {} to a json message".format(duplicates))
self.update(*args[0])
json.loads(raw_post_data, object_pairs_hook=KeyWatcher)
答案 3 :(得分:0)
根据其他用户发布的解决方案,我写的另一种方法是将这些重复项转换为数组:
def array_on_duplicate_keys(ordered_pairs):
"""Convert duplicate keys to arrays."""
d = {}
for k, v in ordered_pairs:
if k in d:
if type(d[k]) is list:
d[k].append(v)
else:
d[k] = [d[k],v]
else:
d[k] = v
return d
然后:
dict = json.loads('{"x": 1, "x": 2}', object_pairs_hook=array_on_duplicate_keys)
为您提供输出:
{'x': [1, 2]}
第一,可以使用以下方法轻松检查条目重复的含义:
if type(dict['x']) is list:
print('Non-unique entry in dict at x, found', len(dict['x']),'repetitions.')