I'm trying to implement a settings option for social media accounts. Therefore, I created a simple streamfield and registered a class as setting. Took some time as I ran into a bug.
That's why I'm curious if the following is a bug or if I just missed something important.
The SocialMediaSettings class:
@register_setting
class SocialMediaSettings(BaseGenericSetting):
body = StreamField([
("social_account", blocks.SocialBlock()),
], null=True, blank=True, use_json_field=True)
api_fields = [
APIField("body"),
]
panels = [
FieldPanel("body")
]
The custom API endpoint:
from rest_framework import viewsets
from rest_framework import serializers
from django.urls import re_path
from site_settings.models import SocialMediaSettings
class SocialMediaSettingsSerializer(serializers.ModelSerializer):
class Meta:
model = SocialMediaSettings
fields = '__all__'
class SocialMediaSettingsViewSet(viewsets.ReadOnlyModelViewSet):
queryset = SocialMediaSettings.objects.all()
serializer_class = SocialMediaSettingsSerializer
@classmethod
def get_urlpatterns(cls):
"""
This returns a list of URL patterns for the endpoint
"""
return [
re_path(r'^$', cls.as_view({'get': 'list'})),
]
As well registered in the API:
api_router.register_endpoint('socials', SocialMediaSettingsViewSet)
Opening the API this all results in the following:
[
{
"id": 1,
"body": "[{\"type\": \"social_account\", \"value\": {\"name\": \"Name\", \"url\": \"https://google.de\", \"icon\": \"iconClass\"}, \"id\": \"8b8a9e45-3fc4-400a-8ed2-7d8b1abba647\"}]"
}
]
I mean, the body is there and the content as well. But this is how it's stored in the database I guess. If I use the streamfield in a normal page, with the default pages API endpoint it's returned this way (which is what I want):
[
{
"id": 1,
"body": [
{
"type": "social_account",
"value": {
"name": "Name",
"url": "https://google.de",
"icon": "iconClass"
},
"id": "a0d35fb8-f4dd-4ea0-b3e1-cd10236e72db"
}
]
}
]
Did I miss something in my API endpoint? Or is it just broken in Wagtail 4.0.1 (Django 4.0)?
from rest_framework import serializers
class SocialMediaSettingsSerializer(serializers.ModelSerializer):
Try changing your serializer to inherit from the BaseSerializer used for pages:
from wagtail.api.v2.serializers import BaseSerializer
class SocialMediaSettingsSerializer(BaseSerializer):
The BaseSerializer inherits from DRF's ModelSerializer but adds code to customize StreamField serialization.