Django序列化器到JSON - 自定义JSON输出格式

10 投票
4 回答
27849 浏览
提问于 2025-04-17 19:20

我刚接触Django,最近需要输出JSON格式的数据,所以我用了下面的Django代码:

data = serializers.serialize("json", Mymodel.objects.all())

这个代码运行得很好,但我得到的输出是:

[{"pk": 8970859016715811, "model": "myapp.mymodel", "fields": {"reviews": "3.5", "title": .....}}]

不过,我希望输出能简单点,要么是:

[{"reviews": "3.5", "title": .....}]

要么是:

[{"id": "8970859016715811", "reviews": "3.5", "title": .....}]

我在想有没有人能告诉我该怎么做才能实现这个。

4 个回答

2

我刚遇到这个问题,发现有同样的困扰。我也是通过自定义序列化器解决的,试过“编辑1”的方法,但效果不太好,因为它把django JSON编码器已经处理好的很多内容(比如小数和日期的序列化)都去掉了。虽然你可以自己重写这些功能,但为什么要这么麻烦呢?我觉得有一种更简单的方法,就是直接继承JSON序列化器,像这样做。

from django.core.serializers.json import Serializer
from django.utils.encoding import smart_text    

class MyModelSerializer(Serializer):
    def get_dump_object(self, obj):
        self._current['id'] = smart_text(obj._get_pk_val(), strings_only=True)
        return self._current

所以,主要负责写字段和模型的部分是在父类的Python序列化器里,通过这种方式,你还可以自动获得django JSON序列化器内置的字段过滤功能。这样调用就可以了。

serializer = MyModelSerializer()
data = serializer.serialize(<queryset>, <optional>fields=('field1', 'field2'))
4

你需要写一个自定义的Json序列化器。像下面这样就可以了:

class FlatJsonSerializer(Serializer):
    def get_dump_object(self, obj):
        data = self._current
        if not self.selected_fields or 'id' in self.selected_fields:
            data['id'] = obj.id
        return data

    def end_object(self, obj):
        if not self.first:
            self.stream.write(', ')
        json.dump(self.get_dump_object(obj), self.stream,
                  cls=DjangoJSONEncoder)
        self._current = None

    def start_serialization(self):
        self.stream.write("[")

    def end_serialization(self):
        self.stream.write("]")

    def getvalue(self):
        return super(Serializer, self).getvalue()

然后你可以这样使用它:

s = FlatJsonSerializer()
s.serialize(MyModel.objects.all())

或者你可以把这个序列化器注册到 django.core.serializers.register_serializer,这样就可以用熟悉的 serializers.serialize 快捷方式了。

如果你需要进一步的定制,可以参考Django的实现:https://github.com/django/django/blob/master/django/core/serializers/json.py#L21-62

7

你可以在序列化函数中添加一个叫'fields'的参数,像这样:

data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))

详细信息请查看:https://docs.djangoproject.com/en/dev/topics/serialization/

编辑 1:

你可以自定义序列化器,只获取你指定的字段。

来自覆盖 Django 对象序列化器以去除指定模型的内容:

from django.core.serializers.python import Serializer

class MySerialiser(Serializer):
    def end_object( self, obj ):
        self._current['id'] = obj._get_pk_val()
        self.objects.append( self._current )

 # views.py
 serializer = MySerialiser()
 data = serializer.serialize(some_qs)

撰写回答