Django的JSON编码添加了额外的\\字符 [英] JSON Encoding with Django adding extra \\ characters

查看:64
本文介绍了Django的JSON编码添加了额外的\\字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个函数,该函数会将包含消息和Django模型实例的字典转换为JSON,然后将其传递回客户端.例如,我在models.py中定义了模型Test.

I'm trying to create a function that will convert a dictionary containing a message and a Django model instance into JSON, that I can pass back to the client. For example, I have the model Test defined in models.py.

from django.db import models

class Test(models.Model):
    test_field = models.CharField(max_length=40)

我已基于 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)

然后,我将创建一个实例以及状态消息:

Then I go about creating an instance of this along with a status message:

t = Test(test_field="hello")
d = {"entry": t, "message": "Congratulations"}
json = dumps(d)

json的内容是:

{"entry": "{\\"pk\\": null, \\"model\\": \\"hours.test\\", \\"fields\\": {\\"test_field\\": \\"hello\\"}", "message": "Congratulations"}

除了所有额外的\\字符外,基本上就是我想要的.为什么将这些插入到json中?如何修改DjangoJSONEncoder而不插入\字符?

Which is basically what I want except for all the extra \\ characters. Why are these being inserted into the json? How can I modify my DjangoJSONEncoder so it doesn't insert the \ characters?

注意

如果我只是手动编码模型实例,我不会得到所有额外的\\字符.

If I just encode the model instance manually I don't get all the extra \\ characters.

s = serialize('json', [t])
s[1:len(s)-2]

这将输出:

{"pk": null, "model": "hours.test", "fields": {"test_field": "hello"}

编辑

根据Daniel Roseman和Leopd的建议,我将DjangoJSONEncoder类修改为以下内容:

Based on the advice of Daniel Roseman and Leopd I modified the DjangoJSONEncoder class to the following:

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)

推荐答案

很遗憾,您的逻辑是错误的.如您所说,最简单的方法"返回一个字符串-但此时您不希望使用字符串,而需要字典.您最终要在一个字符串中序列化一个字符串,因此需要转义多余的引号.

Your logic is wrong, unfortunately. Your "easiest way", as you state, returns a string - but you don't want a string at that point, you want a dictionary. You end up serializing a string within a string, hence the extra quotes which need to be escaped.

幸运的是,serialize函数的格式选项之一是python-将查询集序列化"为Python字典.因此,您只需要:

Luckily, one of the format options for the serialize function is python - which "serializes" the queryset to a Python dictionary. So you just need:

return serialize('python', obj))

这篇关于Django的JSON编码添加了额外的\\字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆