Django,再谈json序列化
我們知道JSON字符串是目前流行的數(shù)據(jù)交換格式,在pyhton中我們通過json模塊,將常用的數(shù)據(jù)類型轉(zhuǎn)化為json字符串。但是,json支持轉(zhuǎn)化的數(shù)據(jù)類型是有限的。
比如,我們通過ORM從數(shù)據(jù)庫查詢出的結(jié)果,試圖通過json序列化:
from .models import UserInfodef index(request):user_list = UserInfo.objects.all()import jsonreturn HttpResponse(json.dumps(user_list))# TypeError: Object of type 'QuerySet' is not JSON serializable報錯,QuerySet不是JSON能序列化的對象。那么有什么辦法可以解決呢?
注意,如果是通過values查詢,如UserInfo.objects.values("name"),查詢出來的結(jié)果雖然也是QuerySet對象,但是其結(jié)構(gòu)是這樣的:<QuerySet [{'name': 'egon'}, {'name': 'sb'}]>, 類似于列表套字典的結(jié)構(gòu)。對于這種情況,我們可以通過list()方法將QuerySet 對象轉(zhuǎn)化為列表,這樣就可以直接用json.dumps()進行序列化了。
方法一:serializers
def index(request):user_list = UserInfo.objects.all()from django.core import serializersuser_list_json = serializers.serialize("json", user_list)return HttpResponse(user_list_json)將返回的結(jié)果放到bejson校驗結(jié)果如下:
[{"model": "app01.userinfo","pk": 1, "fields": {"name": "egon","pwd": "123"} }, {"model": "app01.userinfo","pk": 2,"fields": {"name": "sb","pwd": "123"} } ]注:pk代表主鍵(可以是默認的id主鍵字段,也可以是用戶自定義的主鍵字段)
觀察序列化結(jié)果,發(fā)現(xiàn)這種方式將服務端數(shù)據(jù)庫的表名都暴露了;另外serializers不支持連表序列化,只能拿到另一張表的id。下面我們我們用一種新的方式。
方法二:自定義JSON處理器
查看json.dumps源碼,發(fā)現(xiàn)序列化時,用到了一個參數(shù)cls = JSONEncoder,我們可以繼承它,自定義一個類,重寫它的default方法,來處理我們需要的數(shù)據(jù)類型。比如自定義對時間對象進行轉(zhuǎn)化:
import json from datetime import date from datetime import datetimeclass JsonCustomEncoder(json.JSONEncoder):def default(self, field):if isinstance(field, datetime):return field.strftime('%Y-%m-%d %H:%M:%S')elif isinstance(field, date):return field.strftime('%Y-%m-%d')else:return json.JSONEncoder.default(self, field)下面我們試著序列化一個datetime對象:
def index(request):now = datetime.now()import jsonreturn HttpResponse(json.dumps(now, cls=JsonCustomEncoder))再次訪問http://127.0.0.1:8000/index.html:
是不是成功處理了呢
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的Django,再谈json序列化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Saltstack的modules和g
- 下一篇: 待发箱outbox空间已满