为什么django不使用我的自定义编码器类? [英] Why is django not using my custom encoder class?

查看:70
本文介绍了为什么django不使用我的自定义编码器类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

将WordpressWebsite的实例编码为JSON时,仅显示WordpressWebsite的属性(而没有Website的属性).

When an instance of WordpressWebsite is being encoded into JSON, only the attributes of WordpressWebsite are present (and none of the attributes of Website).

我的目标是编写一个自定义编码器,该编码器会将WordpressWebsite编码为网站.

My goal is to write a custom encoder which will encode a WordpressWebsite as a Website instead.

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

This is what I have so far:

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)

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

This test case runs fine. It does not raise an exception.

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

Does anyone know why WebsiteEncoder.default is not being invoked?

推荐答案

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

Django models are encoded natively with its serializers. Django's own DjangoJSONEncoder supplies a complete serializer for all possible models with any of the default Django datatypes. If you look at the JSONEncoder.default() documentation, you'll notice that you would only supply encoders for datatypes that are not yet known to the encoder.

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

Only if you were using a field type which Django doesn't natively support, you could provide an encoder for it - and only that field type - through .default(). Therefore DjangoJSONEncoder isn't what you're looking for.

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

Trying to make your example work I discovered you can actually customize the process by subclassing 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,
        }

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

After that, you can make your serializer work in the test case like so:

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

这篇关于为什么django不使用我的自定义编码器类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆