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

Django model序列化為json的方法示例

 更新時間:2018年10月16日 09:29:19   作者:Van96  
這篇文章主要介紹了Django model序列化為json的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文環(huán)境

  • Python 3.6.5
  • Django 2.0.4

fix(2018.5.19):最近得知Django 的model基類需要聲明為abstract,故在原來的代碼加入abstract聲明,以免誤導(dǎo)

在Django中,關(guān)于如何將model類序列化為json,一般的話有兩a器

將model類轉(zhuǎn)為字典,再使用json庫的dumps方法轉(zhuǎn)為json

第一種方法就不多講了,直接去看官方文檔就好啦

一般來說,官方提供的方法應(yīng)該都是比較好用和穩(wěn)定的,然而,使用官方的序列化器卻問題不少:

格式丑陋,格式如下,一言難盡:

[
  {
    "pk": "4b678b301dfd8a4e0dad910de3ae245b",
    "model": "sessions.session",
    "fields": {
      "expire_date": "2013-01-16T08:16:59.844Z",
      ...
    }
  }
]

是的,其中pk指的是默認主鍵,model指的是該object的model類型,然后fields才是obj的各種字段...真的是不知如何評價了

  • 不能很好地支持list
  • 對于一些外鍵(包括ManyToManyField等)不是很友好
  • 甚至對于自身的DateField也沒有很好的支持

數(shù)了一通官方序列化器的缺點,當然了,上面的幾個點肯定是有解決方案的,但是啊,我確實不想折騰了嚶嚶嚶。

于是扔出我的解決方案:

  • 新建一個類BaseModel,此類繼承于官方的model類django.db.models.Model
  • 在著個BaseModel中,聲明一個方法,此方法用于生成關(guān)于這個object的字典
  • 使用這個object的字典生成json

關(guān)于生成object的字典的策略是這樣的:

  • 通過反射獲取這個object的所有字段名
  • 根據(jù)字段名獲得某個字段field
  • 如果filed的類型的是int、float、str的話,直接將以 "字段名":字段值 的形式放入字典中
  • 若field的類型是datetime或者date的話,使用date的方式處理,然后放入字典
  • 若field的類型是BaseModel的話,那么就調(diào)用該field的getDict方法遞歸獲得該field對應(yīng)的字典,然后放入字典中
  • 若field的類型是ManyToMany類型,在具體草種中我們使用這個field的all方法來這個field的所有object,然后也是通過getDict方法將其放入到字典中

源碼及使用方法

from django.db import models
import json


class BaseModel(models.Model):
  class Meta:
    abstract = True

  # 返回self._meta.fields中沒有的,但是又是需要的字段名的列表
  # 形如['name','type']
  def getMtMField(self):
    pass

  # 返回需要在json中忽略的字段名的列表
  # 形如['password']
  def getIgnoreList(self):
    pass

  def isAttrInstance(self, attr, clazz):
    return isinstance(getattr(self, attr), clazz)

  def getDict(self):
    fields = []
    for field in self._meta.fields:
      fields.append(field.name)

    d = {}
    import datetime
    for attr in fields:
      if isinstance(getattr(self, attr), datetime.datetime):
        d[attr] = getattr(self, attr).strftime('%Y-%m-%d %H:%M:%S')
      elif isinstance(getattr(self, attr), datetime.date):
        d[attr] = getattr(self, attr).strftime('%Y-%m-%d')
      # 特殊處理datetime的數(shù)據(jù)
      elif isinstance(getattr(self, attr), BaseModel):
        d[attr] = getattr(self, attr).getDict()
      # 遞歸生成BaseModel類的dict
      elif self.isAttrInstance(attr, int) or self.isAttrInstance(attr, float) \
          or self.isAttrInstance(attr, str):
        d[attr] = getattr(self, attr)
      # else:
      #   d[attr] = getattr(self, attr)

    mAttr = self.getMtMField()
    if mAttr is not None:
      for m in mAttr:
        if hasattr(self, m):
          attlist = getattr(self, m).all()
          l = []
          for attr in attlist:
            if isinstance(attr, BaseModel):
              l.append(attr.getDict())
            else:
              dic = attr.__dict__
              if '_state' in dic:
                dic.pop('_state')
              l.append(dic)
          d[m] = l
    # 由于ManyToMany類不能存在于_meat.fields,因而子類需要在getMtMFiled中返回這些字段
    if 'basemodel_ptr' in d:
      d.pop('basemodel_ptr')

    ignoreList = self.getIgnoreList()
    if ignoreList is not None:
      for m in ignoreList:
        if d.get(m) is not None:
          d.pop(m)
    # 移除不需要的字段
    return d

  def toJSON(self):
    import json
    return json.dumps(self.getDict(), ensure_ascii=False).encode('utf-8').decode()

使用方法:

models的所有類都繼承BaseModel類,然后調(diào)用此類的toJSON()方法即可

注意,不知為何,self._meta.fields中沒有包含ManyToManyField字段,因而需要重寫getMtMField方法。例子如下:

class Book(BaseModel):
  name = models.CharField(max_length=50)
  authors = models.ManyToManyField(Author)
  publish = models.ForeignKey(Publisher, on_delete=models.SET_NULL, blank=True, null=True)
  page = models.IntegerField(default=0) # 頁數(shù)
  introduction = models.CharField(max_length=500)
  bookType = models.ManyToManyField(BookType, null=True, blank=True)
  bookTag = models.ManyToManyField(BookTag, null=True, blank=True)
  evaluation = models.FloatField()
  coverUrl = models.CharField(max_length=100, null=True, blank=True)

  def getMtMField(self):
    return ['bookType', 'bookTag']

結(jié)果:

{
  "id":4,
  "name":"Django從入門到放棄",
  "page":123,
  "introduction":"introduction",
  "evaluation":1,
  "bookType":[
    {
      "id":1,
      "name":"類型"
    }
  ],
  "bookTag":[
    {
      "id":2,
      "name":"tag"
    }
  ]
}

后記

源碼有引用,即getDict方法中的第一個for循環(huán),但懶得找原鏈接了,望見諒,特此聲明;

  • 本人python新手,代碼多有不規(guī)范之處,望見諒;
  • 代碼不精,但是也希望能幫到你_;

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python 如何查看pytorch版本

    python 如何查看pytorch版本

    這篇文章主要介紹了python 查看pytorch版本的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • python如何判斷網(wǎng)絡(luò)是否通

    python如何判斷網(wǎng)絡(luò)是否通

    這篇文章主要介紹了python如何判斷網(wǎng)絡(luò)是否通?具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Python文件讀取的3種方法及路徑轉(zhuǎn)義

    Python文件讀取的3種方法及路徑轉(zhuǎn)義

    這篇文章主要介紹了Python文件讀取的3種方法及路徑轉(zhuǎn)義,本文分別給出讀取文件的代碼實例,最后講解了路徑轉(zhuǎn)義的相關(guān)知識、小技巧,需要的朋友可以參考下
    2015-06-06
  • Python?解析獲取?URL?參數(shù)及使用步驟

    Python?解析獲取?URL?參數(shù)及使用步驟

    這篇文章主要介紹了Python?解析獲取?URL?參數(shù)及使用,本文分步驟通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • python中對list去重的多種方法

    python中對list去重的多種方法

    這篇文章主要介紹了python中對list去重的多種方法,本文去重的前提是要保證順序不變,本文給出了多種實現(xiàn)方法,需要的朋友可以參考下
    2014-09-09
  • Python爬蟲之Selenium警告框(彈窗)處理

    Python爬蟲之Selenium警告框(彈窗)處理

    這篇文章主要介紹了Python爬蟲之Selenium警告框(彈窗)處理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • python數(shù)學(xué)建模之三大模型與十大常用算法詳情

    python數(shù)學(xué)建模之三大模型與十大常用算法詳情

    這篇文章主要介紹了python數(shù)學(xué)建模之三大模型與十大常用算法詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感想取得小伙伴可以參考一下
    2022-07-07
  • pyqt5中QThread在使用時出現(xiàn)重復(fù)emit的實例

    pyqt5中QThread在使用時出現(xiàn)重復(fù)emit的實例

    今天小編就為大家分享一篇pyqt5中QThread在使用時出現(xiàn)重復(fù)emit的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • pytorch 自定義參數(shù)不更新方式

    pytorch 自定義參數(shù)不更新方式

    今天小編就為大家分享一篇pytorch 自定義參數(shù)不更新方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • Python的Flask框架Request請求對象詳解

    Python的Flask框架Request請求對象詳解

    這篇文章主要介紹了Python的Flask框架Request請求對象詳解,Flask是一個輕量級的基于Python的web框架,使用 method 屬性可以操作當前請求方法,通過使用 form 屬性處理表單數(shù)據(jù),需要的朋友可以參考下
    2023-08-08

最新評論

福贡县| 井陉县| 天津市| 石台县| 婺源县| 儋州市| 青浦区| 沁水县| 德清县| 宝山区| 石景山区| 洪洞县| 密云县| 赣榆县| 河曲县| 米泉市| 洛南县| 嵩明县| 新昌县| 鄂托克前旗| 梅州市| 扎赉特旗| 剑川县| 蒙山县| 东丽区| 壤塘县| 曲沃县| 冷水江市| 庄河市| 周口市| 萨迦县| 克东县| 织金县| 城步| 微山县| 城固县| 宝坻区| 柳河县| 峨眉山市| 阜新| 宁安市|