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

时间:2012-02-22 21:14: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"
  }
}

我希望将它们序列化以使ExtJS和我的开发人员高兴:

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

我们需要序列化一些比这更复杂的对象。

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

3 个答案:

答案 0 :(得分: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

在上面的示例中,我删除了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
    }

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

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())

答案 1 :(得分:20)

自定义序列化的最佳方法是让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)

答案 2 :(得分:1)

以@ducin的答案为基础:

1)扩展Django的序列化器:

public static void main(String[] args) throws IOException 
    {
    int lowercase = 0;
    int uppercase = 0;
    int length = 0;
    File file1 = new File("input.txt");
    Scanner scanner = new Scanner(file1);
    while(scanner.hasNext())
    {
    String s = scanner.nextLine();
    length = s.length();
    char[] charAnalysis = s.toCharArray();
    for (char element : charAnalysis) 
    {
        if (Character.isUpperCase(element)) 
        {
            uppercase++;
        }
        else if (Character.isLowerCase(element)) 
        {
            lowercase++;
        }
        length = s.length();
    }
    }
    File file2 = new File("output.txt");
        try (PrintStream ps = new PrintStream(file2)) 
        {
            ps.println("Number of characters is " + length);
            ps.println("Number of lower case letters is " + lowercase);
            ps.println("Number of upper case letters is " + uppercase);   
        }
        catch(IOException e) 
        { 

        }
    }
}

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

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

假设您将from django.core.serializers import BUILTIN_SERIALIZERS BUILTIN_SERIALIZERS['json'] = 'may_app.my_module' 放在may_app.my_module中。您也可以将此代码放在Serializer旁边的may_app.my_module中。

3)需要使用序列化程序的位置:

Serializer

,然后像往常一样:

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