When an instance of WordpressWebsite is being encoded into JSON, only the attributes of WordpressWebsite are present (and none of the attributes of Website).
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)
I have the following test case:
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.
Does anyone know why WebsiteEncoder.default is not being invoked?
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With