We know that JSON string is a popular data exchange format, in pyhton we use the json module to convert commonly used data types into json strings. However, the data types supported by json are limited.
For example, we query the results from a database via ORM and try to serialize them via json:
from .models import UserInfo def index(request): user_list = () import json return HttpResponse((user_list)) # TypeError: Object of type 'QuerySet' is not JSON serializable
Error reported, QuerySet is not an object that JSON can serialize.So what's the solution?
Note that if the query is via VALUES, such as("name")
, the result of the query is also a QuerySet object, but its structure is like this:<QuerySet [{'name': 'egon'}, {'name': 'sb'}]>
, similar to the structure of a list set dictionary. For this case, we can transform the QuerySet object into a list by using the list() method, so that we can directly use the()
Perform serialization now.
Method 1: serializers
def index(request): user_list = () from import serializers user_list_json = ("json", user_list) return HttpResponse(user_list_json)
Put the returned result into bejson calibration result is as follows:
[ { "model": "", "pk": 1, "fields": { "name": "egon", "pwd": "123" } }, { "model": "", "pk": 2, "fields": { "name": "sb", "pwd": "123" } } ]
Note: pk stands for primary key (either the default id primary key field or a user-defined primary key field)
Observe the serialization results, found that this way will server-side database table names are exposed; in addition serializers do not support serialization of serialized tables, can only get the id of another table. below we we use a new way.
Method 2: Custom JSON processor
Looking at the source code, I found that when serializing, a parameter cls = JSONEncoder is used, we can inherit it, customize a class and override its default method to handle the data type we need. For example, customize the transformation of the time object:
import json from datetime import date from datetime import datetime class JsonCustomEncoder(): def default(self, field): if isinstance(field, datetime): return ('%Y-%m-%d %H:%M:%S') elif isinstance(field, date): return ('%Y-%m-%d') else: return (self, field)
Here we try to serialize a datetime object:
def index(request): now = () import json return HttpResponse((now, cls=JsonCustomEncoder))
Revisit http://127.0.0.1:8000/.
Additional knowledge:Django ORM Object Json Serialization Issues
Ran into a problem: When serializing a Django ORM Queryset object using () and passing it to the front-end, the program reports an error:
Object of type 'QuerySet' is not JSON serializable
In python, the commonly used json serialization is changed from simplejson base. This json package mainly provides dump,load to realize the serialization and deserialization between dict and string, which is very convenient to complete, but now the problem is that this json package can't serialize the instances of the objects inside the django's models.
After a bit of doozy searching, I found the following solution:
Use the included serializers module:
The #django ORM's Queryset object cannot be serialized by default by direct(), the provided serializers module offers to serialize it to str type # function, serializers are processed and passed to the frontend again, the frontend needs to go through () processing twice to get the original object type, but the format sends the # Changed, need to fetch indexes in a new way. For example: obj['pk'] takes the primary key, obj['fields']["caption"] takes the caption field of obj. leave it (to sb)QuerySet:[<Business: Business object>] turn: [{"model": "", "pk": 1, "fields": {"caption": "develop"}}]
This will allow the front-end to fetch the data normally, except that this field needs to be () processed twice.
As for the use of (id=xx) to get a single object, not Queryset objects, serializers by default can not handle the problem, you can customize the json method to achieve dumps serialization
json default only support python native list, tuple, dict data type object serialization, if you need to extend the other types of objects serialization function, you can modify this way:
import json as default_json from import JSONEncoder class BaseResponse(object): def __init__(self): = True = None = None = None o=BaseResponse() class JsonCustomEncoder(JSONEncoder): def default(self, o): if isinstance(o, BaseResponse): return o.__dict__ return (self, o) o1=(o,cls=JsonCustomEncoder) >>> print(o1) {"message": null, "error": null, "data": null, "status": true} >>> print(type(o1)) <class 'str'> # Specify the cls parameter in the serialization, cls = custom serialization class, in the custom serialization class in the default method to determine, if it is an instance of the specified class, then the class will be converted into a dict format to return, if you specify the instance of the class, then use the default serialization method of the json module. The final return value is of type str.
Above this Django again talk about json serialization is all I have to share with you, I hope to give you a reference, but also hope that you support me more.