Example of Django model serialized to json
- 2020-12-16 06:03:08
- OfStack
In this paper, the environment
Python 3.6.5 Django 2.0.4fix (2018.5.19) : I recently learned that the model base class of Django needs to be declared as abstract, so I added the abstract declaration in the original code to avoid misleading
In Django, how do you serialize the model class to json
Convert the model class to a dictionary, then convert to json using the dumps method of the json library
I won't go into the first method, but just go to the official documents
In general, the officially provided methods should be relatively easy to use and stable, however, using the official serializers is problematic:
The format is ugly. The format is as follows:
[
{
"pk": "4b678b301dfd8a4e0dad910de3ae245b",
"model": "sessions.session",
"fields": {
"expire_date": "2013-01-16T08:16:59.844Z",
...
}
}
]
Yes, where pk refers to the default primary key, model refers to the model type of that object, and then fields is the various fields of obj... Really do not know how to evaluate
Does not support list very well Not very friendly to 1 foreign key (including ManyToManyField, etc.) Even the DateField itself is not well supportedCounting one of the official serializers' shortcomings, of course, there must be a solution to some of the above points, but ah, I really don't want to do a whine.
So throw out my solution:
New class 1 BaseModel, such inheritance in django. Official model db. models. Model In each BaseModel, declare a method that generates a dictionary about the object Use this object dictionary to generate jsonThe strategy for generating object dictionaries is as follows:
Get all the field names for this object by reflection Gets a field field based on the field name If filed is of type int, float, str, put it directly in the dictionary as "field name ": field value If the type of field is datetime or date, use date and put it in the dictionary If field is of type BaseModel, then call the getDict method of that field to recursively obtain the dictionary corresponding to that field and put it in the dictionary If the type of field is ManyToMany, we use the all method of this field to get all object of this field in the specific grass species, and then also by the getDict method to put it into the dictionary
Source code and usage
from django.db import models
import json
class BaseModel(models.Model):
class Meta:
abstract = True
# return self._meta.fields Is not, but is again a list of required field names
# like ['name','type']
def getMtMField(self):
pass
# Return is required in the json A list of field names that are ignored in
# like ['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')
# Special handling datetime The data of
elif isinstance(getattr(self, attr), BaseModel):
d[attr] = getattr(self, attr).getDict()
# Recursive generation BaseModel Of the class 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
# Due to the ManyToMany Class cannot exist in _meat.fields , so subclasses need to be in getMtMFiled Returns these fields
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)
# Remove unwanted fields
return d
def toJSON(self):
import json
return json.dumps(self.getDict(), ensure_ascii=False).encode('utf-8').decode()
Usage:
All classes of models inherit from the BaseModel class and then call the toJSON() method of this class
Note that for some reason the ES97en. _meta. fields does not contain the ManyToManyField field, so you need to override the getMtMField method. Examples are as follows:
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) # Number of pages
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']
Results:
{
"id":4,
"name":"Django From entry to abandonment ",
"page":123,
"introduction":"introduction",
"evaluation":1,
"bookType":[
{
"id":1,
"name":" type "
}
],
"bookTag":[
{
"id":2,
"name":"tag"
}
]
}
Afterword.
Source has a reference, that is, getDict method in the first for loop, but I don't bother to find the original link, please forgive me, I hereby declare;
I python novice, code is not standard, I hope you understand; The code is not perfect, but I hope it can help you.