最近在写项目时,把原来json数据之间储存到数据库中,发现取出来数据时,直接是str格式,一直在找数据库数据转对象的方法,网上都是直接整个model转对象,利用from django.forms.models import model_to_dict的model_to_dict方法
而我现在需要的是单个字段转对象数据格式:
原始数据
[{'id': 57921101, 'url': 'http://p0.meituan.net/shaitu/55f14a094ffa3cbb89b0995e948cc9061334626.jpg'}, {'id': 57921102, 'url': 'http://p1.meituan.net/shaitu/991adde4c3c5a77bf0f5ca6fc016f51f2409281.jpg'}, {'id': 58091765, 'url': 'http://p0.meituan.net/shaitu/29ea42310284606a09111605c39a4a932057637.jpg'}, {'id': 58009106, 'url': 'http://p0.meituan.net/shaitu/7d61eed375ecba855d0f70028709279b2840432.jpg'}]
首先,我想到用json模块来解决:
In [1]: import json
In [3]: original = '''[{'id': 57921101, 'url': 'http://p0.meituan.net/shaitu/55f
...: 14a094ffa3cbb89b0995e948cc9061334626.jpg'}, {'id': 57921102, 'url': 'htt
...: p://p1.meituan.net/shaitu/991adde4c3c5a77bf0f5ca6fc016f51f2409281.jpg'},
...: {'id': 58091765, 'url': 'http://p0.meituan.net/shaitu/29ea42310284606a0
...: 9111605c39a4a932057637.jpg'}, {'id': 58009106, 'url': 'http://p0.meituan
...: .net/shaitu/7d61eed375ecba855d0f70028709279b2840432.jpg'}]'''
In [4]: type(original)
Out[4]: str
In [5]: json.loads(original)
---------------------------------------------------------------------------
JSONDecodeError Traceback (most recent call last)
<ipython-input-5-3a376985b64e> in <module>
----> 1 json.loads(original)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
346 parse_int is None and parse_float is None and
347 parse_constant is None and object_pairs_hook is None and not kw):
--> 348 return _default_decoder.decode(s)
349 if cls is None:
350 cls = JSONDecoder
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py in decode(self, s, _w)
335
336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
338 end = _w(s, end).end()
339 if end != len(s):
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py in raw_decode(self, s, idx)
351 """
352 try:
--> 353 obj, end = self.scan_once(s, idx)
354 except StopIteration as err:
355 raise JSONDecodeError("Expecting value", s, err.value) from None
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
结果在调用json.loads模块时报错了,报错的内容的意思是不能使用单引号,json里面的key需要使用双引号,但是在Django储存到数据库时,会自动转成单引号号,所以我又加了下面两步来解决:
In [6]: original = original.replace('\'','\"')
In [8]: new_list = json.loads(original)
In [9]: new_list
Out[9]:
[{'id': 57921101,
'url': 'http://p0.meituan.net/shaitu/55f14a094ffa3cbb89b0995e948cc9061334626.jpg'},
{'id': 57921102,
'url': 'http://p1.meituan.net/shaitu/991adde4c3c5a77bf0f5ca6fc016f51f2409281.jpg'},
{'id': 58091765,
'url': 'http://p0.meituan.net/shaitu/29ea42310284606a09111605c39a4a932057637.jpg'},
{'id': 58009106,
'url': 'http://p0.meituan.net/shaitu/7d61eed375ecba855d0f70028709279b2840432.jpg'}]
In [10]: type(new_list)
Out[10]: list
这样就可以,但是我发现这种太麻烦,每次都需要解析,所以又发现了第二种办法:使用evel内置函数
In [12]: new1_list = eval(original)
In [13]: new1_list
Out[13]:
[{'id': 57921101,
'url': 'http://p0.meituan.net/shaitu/55f14a094ffa3cbb89b0995e948cc9061334626.jpg'},
{'id': 57921102,
'url': 'http://p1.meituan.net/shaitu/991adde4c3c5a77bf0f5ca6fc016f51f2409281.jpg'},
{'id': 58091765,
'url': 'http://p0.meituan.net/shaitu/29ea42310284606a09111605c39a4a932057637.jpg'},
{'id': 58009106,
'url': 'http://p0.meituan.net/shaitu/7d61eed375ecba855d0f70028709279b2840432.jpg'}]
In [14]: type(new1_list)
Out[14]: list
但是又发现了另外一个问题,evel函数在Python中属于高危函数,所以又找到了第三种方法:ast.literal_eval()方法,此方法会在调用高危方法时自动阻断,比较建议这样写。
In [15]: import ast
In [16]: new3_list = ast.literal_eval(original)
In [17]: type(new3_list)
Out[17]: list
In [18]: new3_list
Out[18]:
[{'id': 57921101,
'url': 'http://p0.meituan.net/shaitu/55f14a094ffa3cbb89b0995e948cc9061334626.jpg'},
{'id': 57921102,
'url': 'http://p1.meituan.net/shaitu/991adde4c3c5a77bf0f5ca6fc016f51f2409281.jpg'},
{'id': 58091765,
'url': 'http://p0.meituan.net/shaitu/29ea42310284606a09111605c39a4a932057637.jpg'},
{'id': 58009106,
'url': 'http://p0.meituan.net/shaitu/7d61eed375ecba855d0f70028709279b2840432.jpg'}]