Bri*_*her 2 python django json django-models
我正在尝试创建一个函数,它将包含一条消息和一个 Django 模型实例的字典转换为 JSON,我可以将其传递回客户端。例如,我在models.py 中定义了模型Test。
from django.db import models
class Test(models.Model):
test_field = models.CharField(max_length=40)
Run Code Online (Sandbox Code Playgroud)
我已经根据这个stackoverflow 问题定义了 simplejson JSONEncoder 的这个扩展:
from django.core.serializers import serialize
from django.utils.simplejson import dumps, loads, JSONEncoder
from django.db.models.query import QuerySet
from django.db import models
from django.utils.functional import curry
class DjangoJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, QuerySet):
# `default` must return a python serializable
# structure, the easiest way is to load the JSON
# string produced by `serialize` and return it
return loads(serialize('json', obj))
if isinstance(obj, models.Model):
#do the same as above by making it a queryset first
set_obj = [obj]
set_str = serialize('json', set_obj)
#eliminate brackets in the beginning and the end
str_obj = set_str[1:len(set_str)-2]
return str_obj
return JSONEncoder.default(self,obj)
# partial function, we can now use dumps(my_dict) instead
# of dumps(my_dict, cls=DjangoJSONEncoder)
dumps = curry(dumps, cls=DjangoJSONEncoder)
Run Code Online (Sandbox Code Playgroud)
然后我开始创建一个实例以及一条状态消息:
t = Test(test_field="hello")
d = {"entry": t, "message": "Congratulations"}
json = dumps(d)
Run Code Online (Sandbox Code Playgroud)
json的内容是:
{"entry": "{\\"pk\\": null, \\"model\\": \\"hours.test\\", \\"fields\\": {\\"test_field\\": \\"hello\\"}", "message": "Congratulations"}
Run Code Online (Sandbox Code Playgroud)
这基本上是我想要的,除了所有额外的 \\
字符。为什么将这些插入到 json 中?如何修改我的 DjangoJSONEncoder 使其不插入 \ 字符?
笔记
如果我只是手动编码模型实例,我不会得到所有额外的\\
字符。
s = serialize('json', [t])
s[1:len(s)-2]
Run Code Online (Sandbox Code Playgroud)
这输出:
{"pk": null, "model": "hours.test", "fields": {"test_field": "hello"}
Run Code Online (Sandbox Code Playgroud)
编辑
根据 Daniel Roseman 和 Leopd 的建议,我将 DjangoJSONEncoder 类修改为以下内容:
class DjangoJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, QuerySet):
# `default` must return a python serializable
# structure, the easiest way is to load the JSON
# string produced by `serialize` and return it
return loads(serialize('python', obj))
if isinstance(obj, models.Model):
#do the same as above by making it a list first
return serialize('python', [obj])[0]
return JSONEncoder.default(self,obj)
Run Code Online (Sandbox Code Playgroud)
不幸的是,你的逻辑是错误的。正如您所说,您的“最简单的方法”返回一个字符串-但此时您不需要字符串,而是需要字典。您最终会在字符串中序列化一个字符串,因此需要转义额外的引号。
幸运的是,该serialize
函数的格式选项之一是python
- 将查询集“序列化”为 Python 字典。所以你只需要:
return serialize('python', obj))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2433 次 |
最近记录: |