Using Django Rest Framework with Wagtails v2 API, we can customize ANY field the way we want. In this short video, we take a look at creating a new field entirely by overwriting an image, but we also look at serializing (JSONifying) an image field from a ForeignKey inside an Orderable. Don't worry, it's not as crazy as it sounds!
In the previous lesson we ran into an issue where a ForeignKey image was not serializable. In this video we're going to address that problem by creating a custom serializer using Django Rest Framework and Wagtails v2 API.
In true Wagtail fashion, we don't need to do very much work. I know I've said this about 10,000 times by now, but this is one of the biggest values behind Wagtail CMS: You can achieve almost anything in such a short amount of time, and still have efficient, maintainable and elegant code.
Let's dive in!
A serializer really just takes some information from Django (or in our case Wagtail) and turns it into a JSON response for the browser and frontend frameworks like React to consume.
from rest_framework.fields import Field
class ImageSerializedField(Field):
"""A custom serializer used in Wagtails v2 API."""
def to_representation(self, value):
"""Return the image URL, title and dimensions."""
return {
"url": value.file.url,
"title": value.title,
"width": value.width,
"height": value.height,
}
This takes the image as a value. You'll see where it's getting the image (as the value) in the code below. But if you wanted to extend this to any other field type, you can absolutely do that too.
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.api import APIField
from wagtail.core.models import Orderable
from wagtail.images.edit_handlers import ImageChooserPanel
class BlogAuthorsOrderable(Orderable):
"""This allows us to select one or more blog authors from Snippets."""
page = ParentalKey("blog.BlogDetailPage", related_name="blog_authors")
author = models.ForeignKey(
"blog.BlogAuthor",
on_delete=models.CASCADE,
)
@property
def author_image(self):
return self.author.image
api_fields = [
# This is using a custom django rest framework serializer
APIField("author_image", serializer=ImageSerializedField()),
]
class BlogAuthor(models.Model):
"""Blog author for snippets."""
image = models.ForeignKey(
"wagtailimages.Image",
on_delete=models.SET_NULL,
null=True,
blank=False,
related_name="+",
)
panels = [
ImageChooserPanel("image"),
]
Interested in seeing the full git commit? Well don't be too shocked when you don't see very many changes ;) Wagtail makes the lives of developers super simple.
https://github.com/CodingForEverybody/learn-wagtail/commit/2c52d07b9723296b6c11b4b2c16c26b6263b9928