Django model序列化為json的方法示例
本文環(huán)境
- Python 3.6.5
- Django 2.0.4
fix(2018.5.19):最近得知Django 的model基類需要聲明為abstract,故在原來的代碼加入abstract聲明,以免誤導
在Django中,關于如何將model類序列化為json,一般的話有兩a器
將model類轉為字典,再使用json庫的dumps方法轉為json
第一種方法就不多講了,直接去看官方文檔就好啦
一般來說,官方提供的方法應該都是比較好用和穩(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中,聲明一個方法,此方法用于生成關于這個object的字典
- 使用這個object的字典生成json
關于生成object的字典的策略是這樣的:
- 通過反射獲取這個object的所有字段名
- 根據字段名獲得某個字段field
- 如果filed的類型的是int、float、str的話,直接將以 "字段名":字段值 的形式放入字典中
- 若field的類型是datetime或者date的話,使用date的方式處理,然后放入字典
- 若field的類型是BaseModel的話,那么就調用該field的getDict方法遞歸獲得該field對應的字典,然后放入字典中
- 若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ù)據
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類,然后調用此類的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']
結果:
{
"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ī)范之處,望見諒;
- 代碼不精,但是也希望能幫到你_;
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
利用Python的folium包繪制城市道路圖的實現(xiàn)示例
這篇文章主要介紹了利用Python的folium包繪制城市道路圖的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
python ftp 按目錄結構上傳下載的實現(xiàn)代碼
這篇文章主要介紹了python ftp 按目錄結構上傳下載的實現(xiàn)代碼,需要的朋友可以參考下2018-09-09
Python實現(xiàn)PPT幻燈片的添加、刪除或隱藏操作
PowerPoint文檔是商務、教育、創(chuàng)意等各領域常見的用于展示、教育和傳達信息的格式,在制作PPT演示文稿時,靈活地操作幻燈片是提高演示效果、優(yōu)化內容組織的關鍵步驟,本文給大家介紹了Python 操作PPT幻燈片- 添加、刪除、或隱藏幻燈片,需要的朋友可以參考下2024-08-08
python利用json和pyecharts畫折線圖實例代碼
這篇文章主要介紹了python利用json和pyecharts畫折線圖實例,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12
使用python實現(xiàn)學生信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了使用python實現(xiàn)學生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-02-02

