为什么django不使用我的自定义编码器类?

时间:2018-11-06 19:58:39

标签: python json django serialization

  1. 我有两节课:网站和WordpressWebsite。
  2. WordpressWebsite会将网站子类化。

将WordpressWebsite的实例编码为JSON时,仅存在WordpressWebsite的属性(而没有Website的属性)。

我的目标是编写一个自定义编码器,它将把WordpressWebsite编码为网站。

这是我到目前为止所拥有的:

from django.core.serializers.json import DjangoJSONEncoder
from websites.models import Website

class WebsiteEncoder(DjangoJSONEncoder):

    def default(self, obj):
        raise Exception()  # TEST
        if isinstance(obj, Website) and hasattr(obj, 'website_ptr'):
            return super().default(obj.website_ptr)
        return super().default(obj)

我有以下测试案例:

from django.core import serializers
from django.test import TestCase
from websites.models.wordpress import WordpressWebsite
from websites.serialize import WebsiteEncoder


class SerializationTest(TestCase):

    def setUp(self):
        self.wordpress = WordpressWebsite.objects.create(
            domain='test.com'
        )

    def test_foo(self):
        JSONSerializer = serializers.get_serializer("json")
        json_serializer = JSONSerializer()
        json_serializer.serialize(
            WordpressWebsite.objects.all(),
            cls=WebsiteEncoder
        )
        data = json_serializer.getvalue()
        print(data)

此测试用例运行正常。它不会引发异常。

有人知道为什么未调用WebsiteEncoder.default吗?

1 个答案:

答案 0 :(得分:1)

Django模型使用其序列化器进行本地编码。 Django自己的DjangoJSONEncoder为具有任何默认Django数据类型的所有可能模型提供了完整的序列化器。如果您查看JSONEncoder.default() documentation,则会注意到您只会为编码器尚不知道的数据类型提供编码器。

仅当您使用的是Django本身不支持的字段类型时,才可以通过.default()为其提供编码器-并且仅提供该字段类型。因此,DjangoJSONEncoder不是您想要的。

尝试使您的示例正常工作,我发现您实际上可以通过将django.core.serializers.json.Serializer子类化来自定义流程:

from django.core.serializers.json import Serializer

class WebsiteSerializer(Serializer):
    def get_dump_object(self, obj):
        return {
            "pk": obj.pk,
            **self._current,
        }

之后,您可以像这样在测试用例中使序列化器工作:

def test_foo(self):
    serializer = WebsiteSerializer()
    data = serializer.serialize(WordpressWebsite.objects.all())
    print(data)