最近在写接口自动化的测试平台,在请求接口回填响应头数据的这一步遇到了一个小问题,想要通过requests库自带的获取响应头的方法(r.headers),然后拿到值后传给前端进行展示,展示效果如下:
开始调试时一切都好好的,但为了将该数据做保存记录的时候出了一些问题,报了一个不常见的错误:
第一反应是django序列化相关的的问题,按报错日志追溯到是代码中通过ORM批量创建数据入库的这一步报错,分析了一下还是没有啥头绪:
打了断点、加注释调试也没发现什么结果,也没有怀疑是因为增加了获取响应header这个操作导致的问题,后面实在无头绪将这部分代码注释后就不报错,能够正常运行了!
然后经过一些调试发现requests返回的响应header是:<class 'requests.structures.CaseInsensitiveDict'>
这个类型,这是一个requests自定义的数据结构,是一个不区分大小写的纯字符串键的数据结构,它也会包含一些byte数据所以在序列其为json字符串时会报错:
class CaseInsensitiveDict(MutableMapping):
"""A case-insensitive ``dict``-like object.
Implements all methods and operations of
``MutableMapping`` as well as dict's ``copy``. Also
provides ``lower_items``.
All keys are expected to be strings. The structure remembers the
case of the last key to be set, and ``iter(instance)``,
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
will contain case-sensitive keys. However, querying and contains
testing is case insensitive::
cid = CaseInsensitiveDict()
cid['Accept'] = 'application/json'
cid['aCCEPT'] == 'application/json' # True
list(cid) == ['Accept'] # True
For example, ``headers['content-encoding']`` will return the
value of a ``'Content-Encoding'`` response header, regardless
of how the header name was originally stored.
If the constructor, ``.update``, or equality comparison
operations are given keys that have equal ``.lower()``s, the
behavior is undefined.
"""
def __init__(self, data=None, **kwargs):
self._store = OrderedDict()
if data is None:
data = {}
self.update(data, **kwargs)
def __setitem__(self, key, value):
# Use the lowercased key for lookups, but store the actual
# key alongside the value.
self._store[key.lower()] = (key, value)
def __getitem__(self, key):
return self._store[key.lower()][1]
def __delitem__(self, key):
del self._store[key.lower()]
def __iter__(self):
return (casedkey for casedkey, mappedvalue in self._store.values())
def __len__(self):
return len(self._store)
def lower_items(self):
"""Like iteritems(), but with all lowercase keys."""
return (
(lowerkey, keyval[1])
for (lowerkey, keyval)
in self._store.items()
)
def __eq__(self, other):
if isinstance(other, Mapping):
other = CaseInsensitiveDict(other)
else:
return NotImplemented
# Compare insensitively
return dict(self.lower_items()) == dict(other.lower_items())
# Copy is required
def copy(self):
return CaseInsensitiveDict(self._store.values())
def __repr__(self):
return str(dict(self.items()))
所以这里我直接将其转换为dict类型就可以解决这个问题:
原:req_log['res_headers'] = r.headers
改:req_log['res_headers'] = dict(r.headers)
我也并未花更多时间去研究该数据结构的功能,这里主要是做个笔记提醒自己。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://quniao.blog.csdn.net/article/details/123713999
内容来源于网络,如有侵权,请联系作者删除!