Получение Django для сериализации объектов без поля «fields» - PullRequest
10 голосов
/ 23 февраля 2012

Итак, я работаю над написанием внутреннего веб-сервиса с использованием Django для создания и использования JSON, а мой коллега работает над внешним интерфейсом ExtJS4.Я использую сериализатор wadofstuff, чтобы я мог сериализовать вложенные объекты.

У моего коллеги проблемы с анализом json, в частности, из-за того, что Django помещает поля для объекта в поле «fields».Краткий пример:

Способ сериализации сейчас:

{
  "pk":1,
  "model":"events.phone",
  "fields":{
     "person":1,
     "name":"Cell",
     "number":"444-555-6666"
  }
}

Способ, которым я хотел бы сериализовать их, чтобы сделать ExtJS и моего коллегу-разработчика счастливым:

{
  "pk":1,
  "model":"events.phone",
  "person":1,
  "name":"Cell",
  "number":"444-555-6666"
}

Нам нужно будет сериализовать некоторые объекты, которые намного сложнее, чем этот.

Есть ли способ написать мои сериализации вручную, чтобы сериализатор Django или wadofstuff не использовал поле полей?

Ответы [ 3 ]

28 голосов
/ 23 апреля 2013

Кроме того, в django есть более гибкий способ изменения вывода JSON общей модели.Взгляните на исходный код модуля django.core.serializers (который довольно прост - я новичок в Python) и переопределите метод get_dump_object:

from django.core.serializers.json import Serializer as Builtin_Serializer

class Serializer(Builtin_Serializer):
    def get_dump_object(self, obj):
        return self._current

В приведенном выше примере я избавляюсь от обоих1006 * и model, и я немедленно возвращаю поля.

Исходный код:

def get_dump_object(self, obj):
    return {
        "pk": smart_text(obj._get_pk_val(), strings_only=True),
        "model": smart_text(obj._meta),
        "fields": self._current
    }

. Решение исходного вопроса может быть, например,

def get_dump_object(self, obj):
    metadata = {
        "pk": smart_text(obj._get_pk_val(), strings_only=True),
        "model": smart_text(obj._meta),
    }
    return dict(metadata.items() + self._current.items())
21 голосов
/ 23 февраля 2012

Лучший способ настроить вашу сериализацию - это заставить Django сначала сериализовать в команды Python.Затем вы можете постобработать эти диктовки как вам угодно, прежде чем вывести их в JSON:

# this gives you a list of dicts
raw_data = serializers.serialize('python', Phone.objects.all())
# now extract the inner `fields` dicts
actual_data = [d['fields'] for d in raw_data]
# and now dump to JSON
output = json.dumps(actual_data)
1 голос
/ 13 октября 2018

основываясь на ответе Дучина:

1) расширить сериализатор Django:

from django.core.serializers.json import Serializer as DjangoSerializer

class Serializer(DjangoSerializer):  # name must be Serializer
    def get_dump_object(self, obj):
        self._current['id'] = smart_text(obj._get_pk_val(), strings_only=True)
        self._current['model'] = smart_text(obj._meta)
        return self._current

2) обновить модуль, который Django будет использовать для типа 'json':

from django.core.serializers import BUILTIN_SERIALIZERS

BUILTIN_SERIALIZERS['json'] = 'may_app.my_module'

при условии, что вы поместили Serializer выше в may_app.my_module. Вы можете поместить этот код также в may_app.my_module, рядом с Serializer.

3) откуда вам нужно использовать сериализатор:

from django.core import serializers
from my_app import my_module # to do the update

и затем как обычно:

pickle = serializers.serialize('json', MyModel.objects.all())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...