Django: управление сериализацией JSON - PullRequest
1 голос
/ 27 февраля 2011

Есть ли способ управления сериализацией JSON в Django? Простой код ниже вернет сериализованный объект в json:

co = Collection.objects.all()
c = serializers.serialize('json',co)

JSON будет выглядеть примерно так:

[
    {
        "pk": 1,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "architecture",
            "name": "\u0413\u043e\u0440\u043e\u0434 \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430",
            "sortOrder": 0
        }
    },
    {
        "pk": 2,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "nature",
            "name": "\u041f\u0440\u0438\u0440\u043e\u0434\u0430",
            "sortOrder": 1
        }
    },
    {
        "pk": 3,
        "model": "picviewer.collection",
        "fields": {
            "urlName": "objects",
            "name": "\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u043d\u0430\u0442\u044e\u0440\u043c\u043e\u0440\u0442",
            "sortOrder": 2
        }
    }
]

Вы можете видеть, что он сериализует его таким образом, что вы можете воссоздать всю модель, если вы захотите сделать это в какой-то момент - достаточно справедливо, но не очень удобно для простого JS AJAX в моем случае: I хочу свести трафик к минимуму и сделать все это немного понятнее.

То, что я сделал, я создал представление, которое передает объект в шаблон .json, и шаблон будет делать что-то вроде этого, чтобы генерировать более приятный вывод json:

[
{% if collections %}
    {% for c in collections %}
{"id": {{c.id}},"sortOrder": {{c.sortOrder}},"name": "{{c.name}}","urlName": "{{c.urlName}}"}{% if not forloop.last %},{% endif %}
    {% endfor %}
{% endif %}
]

Это работает, и результат намного (?) Лучше:

[
    {
        "id": 1,
        "sortOrder": 0,
        "name": "Город и архитектура",
        "urlName": "architecture"
    },
    {
        "id": 2,
        "sortOrder": 1,
        "name": "Природа",
        "urlName": "nature"
    },
    {
        "id": 3,
        "sortOrder": 2,
        "name": "Объекты и натюрморт",
        "urlName": "objects"
    } 
]

Однако меня беспокоит тот факт, что мое решение использует шаблоны (дополнительный шаг в обработке и возможное влияние на производительность), и для его обслуживания потребуется ручная работа, например, обновлю ли я модель.

Я думаю, что генерация json должна быть частью модели (поправьте меня, если я ошибаюсь) и сделана с нативной реализацией python-json и django, но не могу понять, как заставить ее отбросить биты, которые я делаю не хочу.

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

Ответы [ 4 ]

2 голосов
/ 27 февраля 2011

Это действительно легко.Быстрый пример:

from django.http import HttpResponse
from django.utils import simplejson

def simple_view(request):
    response = {'string': "test",
                'number': 42,
                'array': [1, 2, 3],
                'js_object': dict(foo="bar")}
    return HttpResponse(simplejson.dumps(response),
                        mimetype="application/json")

Это представление вернет эквивалент следующего JSON:

{"string": "test",
 "number": 42,
 "array": [1, 2, 3],
 "js_object": {foo: "bar"}}

РЕДАКТИРОВАТЬ: И да, Ассаф Лави прав, ваш шаблон может выбросить недействительный JSON.1007 *

2 голосов
/ 27 февраля 2011

Я бы предложил вам использовать библиотеку json для кодирования ваших данных, вместо того, чтобы просто создавать json-подобную строку самостоятельно. Код выше, кажется, не обрабатывает экранирование правильно, с одной стороны. И нет ничего хорошего в написании собственного сериализатора (кроме ошибок).

0 голосов
/ 03 января 2013
def view( request):
    m_all = list(model.objects.all().values())

    return HttpResponse(simplejson.dumps(m_all))

Это должно решить проблему.Использование values ​​() и преобразование в список должно привести к желаемому результату.

0 голосов
/ 27 февраля 2011

Вместо того, чтобы что-то писать самостоятельно, позвольте Piston выполнить сериализацию моделей Django в JSON.По умолчанию он просто сериализует поля модели, а не метаданные.И вы можете легко перечислить, какие поля - даже связанные поля - включить или исключить.Никаких дополнительных шаблонов и очень мало кода для просмотра.

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