让Django序列化没有"fields"字段的对象

jaw*_*ont 12 django json extjs4

所以我正在使用Django编写后端Web服务来创建和使用JSON,我的同事正在研究ExtJS4前端.我正在使用wadofstuff序列化程序,因此我可以序列化嵌套对象.

我的同事在解析json时遇到了麻烦,特别是Django将对象的字段放在"fields"字段中.一个简短的例子:

事情现在被序列化的方式:

{
  "pk":1,
  "model":"events.phone",
  "fields":{
     "person":1,
     "name":"Cell",
     "number":"444-555-6666"
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望将它们序列化以使ExtJS和我的开发人员满意的方式:

{
  "pk":1,
  "model":"events.phone",
  "person":1,
  "name":"Cell",
  "number":"444-555-6666"
}
Run Code Online (Sandbox Code Playgroud)

我们需要序列化一些比这复杂得多的对象.

有没有办法手动编写我的序列化以使Django或wadofstuff序列化器不使用字段字段?

duc*_*cin 28

此外,还有一种更灵活的方法来修改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
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我摆脱了两个pkmodel键,我立即返回字段.

原始代码是:

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
    }
Run Code Online (Sandbox Code Playgroud)

原始问题的解决方案可以是,例如:

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())
Run Code Online (Sandbox Code Playgroud)


Dan*_*man 23

自定义序列化的最佳方法是让Django首先序列化为Python dicts.然后,您可以在将它们转储到JSON之前对这些dicts进行后期处理(不管您喜欢):

# 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)
Run Code Online (Sandbox Code Playgroud)


meh*_*met 5

基于@ducin 的回答:

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
Run Code Online (Sandbox Code Playgroud)

2) 更新 Django 将用于类型 'json' 的模块:

from django.core.serializers import BUILTIN_SERIALIZERS

BUILTIN_SERIALIZERS['json'] = 'may_app.my_module'
Run Code Online (Sandbox Code Playgroud)

假设您将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
Run Code Online (Sandbox Code Playgroud)

然后像往常一样:

pickle = serializers.serialize('json', MyModel.objects.all())
Run Code Online (Sandbox Code Playgroud)