Headless Wagtail CMS: Custom Image Serializers

This video is from Wagtail CMS 2023 .

Headless Wagtail CMS: Custom Image Serializers
0:06:36
Published November 29, 2023
3,318 views

While working with Wagtail's v2 API, sometimes you'll run into a scenario where you need to serialize (turn model fields into JSON) on your own. Wagtail's API will handle as much of it as it possibly can, but it's impossible to know every possible situation. That's where Django Rest Framework comes in.

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!

Tutorial: https://learnwagtail.com/tutorials/headless-cms-custom-wagtail-image-serializer/

Learn Wagtail from scratch with the official Wagtail for Beginners Course
https://learnwagtail.com/wagtail-for-beginners/

Git Commit: https://github.com/CodingForEverybody/learn-wagtail/commit/2c52d07b9723296b6c11b4b2c16c26b6263b9928

Used in this video: Wagtail 2.4, Python 3.7, Django 2.1.5

Outro Template made by Grabster - Youtube.com/GrabsterTV #Wagtail #Django #Python

Summary

Wagtail’s headless API cannot serialize a Wagtail image object automatically when it is exposed through an orderable’s API fields, producing a “not JSON serializable” error. The solution is to create a custom Django REST Framework field that implements `to_representation()` and returns a dictionary containing selected image data, such as the file URL, title, width, and height, then assign that field through the API field’s `serializer` parameter. The same pattern can be applied to other fields by changing what the custom serializer returns.

Key takeaways

  • A Wagtail image object exposed directly in an API field is not JSON serializable by default.
  • A custom DRF field can define `to_representation(self, value)` to convert the image into a dictionary.
  • The serializer can return properties such as `value.file.url`, `value.title`, `value.width`, and `value.height`.
  • Pass the custom field class to the API field’s `serializer` parameter, including parentheses when instantiating it.
  • The same custom-serializer approach works with fields other than images.

Summarised automatically from the transcript.

Transcript

1,050 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:00

Hello again. In our last lesson, we discovered a tricky little bug where we could not turn an image into JSON in our Wagtail headless. CMS in our API. And I'm going to recreate that problem for you right now. So we were in our blog models, and the model that we were in was our blog authors orderable And we wanted to expose the author, but because the author is a foreign key to a blog author, we had to write a couple of properties. And one of those properties that we ended up writing was an image. And I'm going to duplicate that issue for you right now. Now the way that we got around not being able to access the image and the website.

0:48

And the name was by writing properties that traversed through self. author and then returned simply the name and the website as a property, and we exposed that property. So no big deal there. And I'm going to change this to image. So this is going to get self. author. image. That's this one here. And in our API fields, let's also add image. And I'm gonna boot up my browser, give this a nice healthy refresh, and we're going to see this ugly guy. What is this all about? Object of type images, not JSON serializable Well, I'm gonna say that error is probably properly named. However, I'm gonna say it is not not JSON serializable.

1:33

It is absolutely serializable. We just have to add our own serializer So let's again open up our editor, I'm using Visual Studio Code, and let's work with Django's Rest framework just a little bit Now this course is not going to dive into Django Rest framework really more than this to be honest. All we need to do is we need to tell our image to use a custom serializer. So let's go ahead from rest framework dot fields import field and this is simply a rest framework field And let's add a new class here. So let's call this a image URL field. No, let's just call this image serialized field. Something like that.

2:18

The name honestly is not super important. Now this has a method in here called to representation. So let's do def. to representation and the parameter list is simply going to take self and value And we are simply going to return a dictionary. So return a dictionary with a thing here. Let's do this. A thing here. something custom. And then lastly, if we go back down to where we're trying to expose our image, which is here. We can give this a custom serializer. So we say serializer is equal to, as you can see, by default it is none, but we want this to be an image

3:06

serialized field And that is a class. So you add the brackets. In the terminal, everything looks a-okay, so let's open up our browser and refresh. And we're going to see something interesting. So I'm going to scroll on down, scroll on down. And where we're working with is our blog authors. This is our orderable. Orderable ID of one meta. The type is blog. blog authors orderable, so we know it's an orderable because I named it explicitly. We gave it an author name, an author website, and the author image, as you can see, is a dictionary. With a key value pair of a thing here and something custom. And that really just matches perfectly, actually. It perfectly matches this dictionary right here.

3:54

Now let's say we want something to do with the actual image itself. We don't want to just hard code something like this. So let's create a key for the URL Let's create a key for maybe the title. Let's also create a key for let's see width and height. Width and height. And then for our URL, the key, or not the key, the value is actually going to be value. file dot url. The title is going to be value. title. Value, by the way, is our image. It's what we're passing in here. So if I scroll down, our value is whatever this is. And this is the image. So we've got value title in there, let's add a comma, let's add the width, value.

4:44

width, and value dot height Now this does not need to be called value. I guess we could rename this to anything we like. I'm just going to use value because that's sort of the stock way of describing this. So I'm going to save and refresh my browser, and we're going to see here that our author image is now the author image. It has the title and it has the uh the source, the source height and width. And that, my friends, is all we have to do to get this to work. Now you do not have to do this with just a custom image. You can do this on any field. Any field is serializable with a serializer parameter.

5:30

And you just give it the class name So I would urge you to try this out with website or the blog author name. And just change what it returns in here. Just test it out, get a feel for it. There's no better way to learn than to experiment. Now this has been a really straightforward lesson, nice and quick, straight to the point. If you want access to this code, you can always access it. from GitHub at github. com slash coding for everybody slash learn dash wagtail. If you want to see just this git commit, you can check out the link in the description down below. I will always leave you the gith commit link if there is one. My name is Caleb Tallin. I'm an author on LearnWagtail.

6:16

com where you can find more videos like this. If you found this to be helpful to any degree, don't forget, you can share, you can comment, you can subscribe. Or if you're going down the YouTube rabbit hole, you can always click the link in the top right to watch all the other videos in this playlist. Thanks for joining me, and I will see you in the next video.

Questions this talk answers

How do I serialize a Wagtail image in a headless API as JSON?

Create a custom Django REST Framework field with a `to_representation` method, then assign that field using the image property's `serializer` parameter. This converts the image object into a JSON-serializable dictionary.

Discussed at 1:33

What image fields can I include in a custom Wagtail image serializer?

The serializer can return a dictionary containing values such as the image URL (`value.file.url`), title, width, and height.

Discussed at 3:54

Can I use a custom serializer for fields other than images in Wagtail?

Yes. The same `serializer` parameter can be used with any field; provide a serializer class and customize what its `to_representation` method returns.

Discussed at 5:30

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from Wagtail CMS