序列化包含Django查询集的对象

6 投票
1 回答
4919 浏览
提问于 2025-04-15 18:12

Django提供了一些工具来处理查询集的序列化(django.core.serializers),但是如果查询集在其他对象里面,比如字典里,该怎么处理呢?

我想要序列化下面这个字典:

dictionary = { 'alfa': queryset1, 'beta': queryset2, } 

我决定使用simplejson(这个在django里自带)。我这样扩展了simplejson.JSONEncoder

from django.utils import simplejson
from django.core import serializers

class HandleQuerySets(simplejson.JSONEncoder):
     """ simplejson.JSONEncoder extension: handle querysets """
     def default(self, obj):
         if isinstance(obj, QuerySet):
             return serializers.serialize("json", obj, ensure_ascii=False)

         return simplejson.JSONEncoder.default(self, obj)

然后我执行:simplejson.dumps( dictionary, cls=HandleQuerySets),但是返回的字典看起来是这样的:

{ "alfa": "[{\"pk\": 1, \"model\": \"someapp.somemodel\", \"fields\": {\"name\": \"alfa\"}}]",
  "beta": "[{\"pk\": 1, \"model\": \"someapp.somemodel\", \"fields\": {\"name\": \"alfa\"}}]" }

在字典里,Django生成的JSON被当作字符串插入,而不是作为JSON格式。请问我哪里做错了?

1 个回答

10

正确的做法是:

from django.utils import simplejson
from django.core import serializers
from django.db.models.query import QuerySet

class HandleQuerySets(simplejson.JSONEncoder):
     """ simplejson.JSONEncoder extension: handle querysets """
     def default(self, obj):
         if isinstance(obj, QuerySet):
             return serializers.serialize("python", obj, ensure_ascii=False)
         return simplejson.JSONEncoder.default(self, obj)

因为 serializers.serialize("json", [...]) 返回的是一个字符串;如果你请求 python 的序列化器,你会得到一个字典,而 json 会对你编码器的 default 方法返回的内容进行编码。想了解更多细节,可以查看 json 文档

你需要在你的编码器类中处理更多类型(比如日期时间对象),但大致思路就是这样。

撰写回答