最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django 再談一談json序列化

 更新時間:2020年03月16日 12:13:11   作者:Ayhan_huang  
這篇文章主要介紹了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 UserInfo

def index(request):
  user_list = UserInfo.objects.all()
  import json
  return 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()進(jìn)行序列化了。

方法一:serializers

def index(request):
  user_list = UserInfo.objects.all()
  from django.core import serializers
  user_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代表主鍵(可以是默認(rèn)的id主鍵字段,也可以是用戶自定義的主鍵字段)

觀察序列化結(jié)果,發(fā)現(xiàn)這種方式將服務(wù)端數(shù)據(jù)庫的表名都暴露了;另外serializers不支持連表序列化,只能拿到另一張表的id。下面我們我們用一種新的方式。

方法二:自定義JSON處理器

查看json.dumps源碼,發(fā)現(xiàn)序列化時,用到了一個參數(shù)cls = JSONEncoder,我們可以繼承它,自定義一個類,重寫它的default方法,來處理我們需要的數(shù)據(jù)類型。比如自定義對時間對象進(jìn)行轉(zhuǎn)化:

import json
from datetime import date
from datetime import datetime

class 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 json
  return HttpResponse(json.dumps(now, cls=JsonCustomEncoder))

再次訪問http://127.0.0.1:8000/index.html:

補(bǔ)充知識:Django ORM對象Json序列化問題

碰到了一個問題:在使用json.dumps()序列化Django ORM的Queryset對象,傳遞給前端的時候,程序報錯:

Object of type 'QuerySet' is not JSON serializable

在python 中,常用的json 的序列化是從simplejson 基礎(chǔ)上改變而來。這個json 包主要提供了dump,load 來實現(xiàn)dict 與 字符串之間的序列化與反序列化,這很方便的可以完成,但現(xiàn)在的問題是,這個json包不能序列化 django 的models 里面的對象的實例。

經(jīng)過一番度娘搜索,發(fā)現(xiàn)有如下解決方案:

使用django.core自帶的serializers模塊:

#django ORM的 Queryset對象默認(rèn)無法被直接json.dumps()序列化,django.core提供的serializers模塊提供將其序列化成str類型
#的功能,serializers處理后,再次json.dumps傳給前端,前端需要經(jīng)過兩次json.Parse()處理,才能得到原對象類型,但是格式發(fā)
#生了變化,需要按新的方式取索引.例如:obj['pk']取主鍵,obj['fields']["caption"]取obj的caption字段
由QuerySet:[<Business: Business object>]
變?yōu)榱耍?
[{"model": "cmdb.business", "pk": 1, "fields": {"caption": "develop"}}]

這樣前端就可以正常獲取數(shù)據(jù)了,只不過此字段需要兩次json.Parse()處理。

至于使用models.Host.objects.get(id=xx)的方式獲取到單個對象,而非Queryset對象,serializers默認(rèn)也無法處理的問題,可以自定義json方法來實現(xiàn)dumps序列化

json默認(rèn)只支持python原生的list、tuple、dict數(shù)據(jù)類型對象的序列化,若需要擴(kuò)展其他類型對象的序列化功能,可以這樣修改:

import json as default_json
from json.encoder import JSONEncoder


class BaseResponse(object):
  def __init__(self):
    self.status = True
    self.message = None
    self.data = None
    self.error = None
o=BaseResponse()

class JsonCustomEncoder(JSONEncoder):
  def default(self, o):
    if isinstance(o, BaseResponse):
      return o.__dict__
    return JSONEncoder.default(self, o)

o1=json.dumps(o,cls=JsonCustomEncoder)


>>> print(o1)
{"message": null, "error": null, "data": null, "status": true}
>>> print(type(o1))
<class 'str'>
#在序列化時指定cls參數(shù),cls=自定義的序列化類,在自定義序列化類的default方法中判斷,如果是指定的類的實例的話,則將該類轉(zhuǎn)換成dict格式返回,若指定類的實例,則使用json模塊默認(rèn)的序列化方法。最終得到的return值為str類型。

以上這篇Django 再談一談json序列化就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用PyQt5實現(xiàn)一個鼠標(biāo)連點器

    使用PyQt5實現(xiàn)一個鼠標(biāo)連點器

    這篇文章主要為大家詳細(xì)介紹了如何使用PyQt5實現(xiàn)一個鼠標(biāo)連點器,從而對QVBoxLayout、QHBoxLayout和QStackedWidget進(jìn)行一個回顧復(fù)習(xí),需要的可以參考一下
    2023-12-12
  • Mac中升級Python2.7到Python3.5步驟詳解

    Mac中升級Python2.7到Python3.5步驟詳解

    本篇文章主要介紹了Mac中升級Python2.7到Python3.5步驟詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • python3+opencv3識別圖片中的物體并截取的方法

    python3+opencv3識別圖片中的物體并截取的方法

    今天小編就為大家分享一篇python3+opencv3識別圖片中的物體并截取的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • Python中celery的使用

    Python中celery的使用

    Celery是一個簡單、靈活且可靠的,處理大量消息的分布式系統(tǒng),專注于實時處理的異步任務(wù)隊列,同時也支持任務(wù)調(diào)度。接下來通過本文給大家介紹Python中celery的使用詳解,感興趣的朋友一起看看吧
    2021-08-08
  • Python中pip安裝非PyPI官網(wǎng)第三方庫的方法

    Python中pip安裝非PyPI官網(wǎng)第三方庫的方法

    這篇文章主要介紹了Python中pip安裝非PyPI官網(wǎng)第三方庫的方法,pip最新的版本(1.5以上的版本), 出于安全的考 慮,pip不允許安裝非PyPI的URL,本文就給出兩種解決方法,需要的朋友可以參考下
    2015-06-06
  • PyCharm控制臺堆棧亂碼問題解決方案

    PyCharm控制臺堆棧亂碼問題解決方案

    PyCharm環(huán)境都已經(jīng)配置成了UTF-8編碼,控制臺打印中文也不會出現(xiàn)亂碼,但報錯堆棧信息中如果有中文會出現(xiàn)中文亂碼,遇到這樣的問題如何解決呢,下面小編給大家?guī)砹薖yCharm控制臺堆棧亂碼問題解決方案,感興趣的朋友一起看看吧
    2023-12-12
  • 利用Python開發(fā)微信支付的注意事項

    利用Python開發(fā)微信支付的注意事項

    如今支付的引入是很多互聯(lián)網(wǎng)產(chǎn)品都需要的。為了讓用戶用著更方便快捷,集成像支付寶、微信支付這樣的第三方支付也就成了常有的事。今天跟著小編就來看看微信支付開發(fā)中幾個值得注意的地方,涉及代碼之處均用 Python 編寫。
    2016-08-08
  • python wav模塊獲取采樣率 采樣點聲道量化位數(shù)(實例代碼)

    python wav模塊獲取采樣率 采樣點聲道量化位數(shù)(實例代碼)

    這篇文章主要介紹了python wav模塊獲取采樣率 采樣點聲道量化位數(shù),本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 利用Python?Difflib庫強(qiáng)大的文字比較功能快速輕松查重

    利用Python?Difflib庫強(qiáng)大的文字比較功能快速輕松查重

    這篇文章主要介紹了利用Python?Difflib庫強(qiáng)大的文字比較功能快速輕松查重實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Python實現(xiàn)新浪博客備份的方法

    Python實現(xiàn)新浪博客備份的方法

    這篇文章主要介紹了Python實現(xiàn)新浪博客備份的方法,涉及Python正則操作,字符串操作及文本操作的相關(guān)技巧,需要的朋友可以參考下
    2016-04-04

最新評論

和田县| 报价| 华蓥市| 辽源市| 长泰县| 陆良县| 桓仁| 峡江县| 罗平县| 剑河县| 荔波县| 亚东县| 西藏| 盐山县| 扎兰屯市| 桦南县| 于都县| 犍为县| 登封市| 瑞金市| 沛县| 正宁县| 布尔津县| 潼关县| 马山县| 青阳县| 沁水县| 台北县| 长乐市| 岗巴县| 霞浦县| 凤山县| 沂水县| 正镶白旗| 兴宁市| 永康市| 木里| 合川市| 宁强县| 博客| 万年县|