Кодировка JSON с добавлением Django дополнительных символов \\ - PullRequest
1 голос
/ 20 мая 2011

Я пытаюсь создать функцию, которая преобразует словарь, содержащий сообщение и экземпляр модели Django, в JSON, который я могу передать обратно клиенту.Например, у меня есть модель Test, определенная в models.py.

from django.db import models

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

Я определил это расширение JSONEncoder simplejson на основе вопроса stackoverflow :

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)

Затем я приступаю к созданию экземпляра этого вместе с сообщением о состоянии:

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, чтобы он не вставлял \ символы?

ПРИМЕЧАНИЕ

Если я просто закодирую экземпляр модели вручную, я не получу вседополнительные \\ символов.

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

Это выводит:

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

РЕДАКТИРОВАТЬ

По совету Даниэля Роземана и Леопда Iизменил класс 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)

Ответы [ 2 ]

4 голосов
/ 20 мая 2011

Ваша логика неверна, к сожалению. Ваш «самый простой способ», как вы заявляете, возвращает строку - но вам не нужна строка в этот момент, вам нужен словарь. Вы заканчиваете сериализацией строки внутри строки, отсюда и дополнительные кавычки, которые необходимо экранировать.

К счастью, одним из параметров формата для функции serialize является python, который «сериализует» набор запросов в словарь Python. Так что вам просто нужно:

return serialize('python', obj))
1 голос
/ 20 мая 2011

Вы сериализуете свой объект модели Test в строку JSON, а затем поле entry в d представляет собой сериализованную строку, а не структуру данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...