Video Tour of Wagtail 8.0
Published September 19, 2026
This video is from Wagtail CMS 2023 .
In the last lesson we enabled Wagtails v2 API but we didn't have access to our custom fields.. yet! In this lesson we'll learn how, in just 4 lines of code, we can make a custom Wagtail Page field show up in our API. And it only gets easier from here.
How to enable Wagtails v2 API (Headless CMS): https://www.youtube.com/watch?v=VT9-qdI96rE
Tutorial: https://learnwagtail.com/tutorials/headless-cms-exposing-custom-page-fields-v2-api/
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/9ce96e6cbb047224e0fe6cf39e155687b0dfe274 #Wagtail #Django #Python
Wagtail’s v2 API does not expose custom fields on a page model by default, but adding them is straightforward: import `APIField` and declare an `api_fields` list on the page class. The example exposes a banner title, rich-text subtitle, image, and page-linked call to action, showing how the API returns text, image metadata and URLs, and linked page details. The speaker also demonstrates using the `fields` query parameter to exclude or request fields, reducing unnecessary response data and potentially improving performance.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Hello and welcome back to another lesson on learning Wagtail. In the previous lesson, we learned all about installing and enabling the Wagtail V2 API so that we can create some sort of headless CMS for React or View. or Angular or some sort of front-end framework to consume. Now at the end of the video, we got to a place where uh we were looking at items or uh a particular page and so we were looking at actually page three which is our homepage And we noticed that we actually had missing information in here. We didn't have everything that we needed. And if we open up our models. py We can see that in our homepage, so I'm in home slash models. Oh there it is. My site homodels. py and I'm in the home page class
We actually have a banner title, subtitle, image, and a banner CTA, which is a foreign key to another page. Now, none of this stuff actually shows up in our API. And the reason for that is because we have to explicitly tell it to show up in here. Now, if you're a little bit concerned that this might get really difficult. I'm gonna tell you it's not. It is really easy. And in fact, in I think it's four lines of code, we can add one custom field in here. With five lines of code, we can add two, and so on and so on. It's really, really easy. And in fact, I'm going to demonstrate that for you right now. So we're going to customize our homepage just a little bit, and we need to import well this is our Wagtail API. So let's go in here. Wagtail, Wagtail, Wagtail.
Let's go to the very top here. From Wagtail. api import API field. So that's step one. And step two is really easy. I like to keep these together, so if there's a content panel, yeah I scrolled right by it. There's one more that we have have to add in here now. It's called API fields. API fields. And this is going to be a list. And we're going to give it an API field with which one do we want in here? Let's put our banner title. Bruce Banner, he is the title that we need. So I'm gonna save that. I already have my server running and when I refresh Hello Banner title is in there. Look at that. Isn't that nice? Okay, so that was one, two, three.
Four lines of code. Now we want to add one more, so let's add our banner subtitle Okay, I'm just gonna copy and paste that. We also have a banner image in here, so let's go and add that banner image. And we have a banner CTA. And these are all if I remember correctly. different types of data. So our banner CTA is a foreign key. Banner image, actually that's also going to be a foreign key, but that's going to be to an image. Subtitle is going to be a rich text field, and our banner title is going to be a regular char field. So save that, refresh our page, and our banner subtitle, look at that, has parsed HTML in it already. Our banner image gives us an image ID, gives us uh metadata.
So what type of what type of image is this? Uh is this using wagtailimages. image or is it using a custom image class? This will give you a detail URL and a download URL. So you can simply stick these into your application at any point in time and someone can view the original image And it also gives you a title. Now if you wanted more details about that, you could simply click on this link in here, but because I'm missing the port and I don't want to change that at the moment. I'm simply going to paste this into my URL and it's going to be localhost port 8000 slash API slash V2 slash images slash 2. And so this gives us exactly what we're looking for: images, uh, very similar data.
We notice that this comes in a single object, it's not in some sort of list anymore, and it gives us a width and a height So that's the default width and height that comes from our default image. Also gives us a list of tags. So you get a little more information when you go to the detail view. And our banner CTA is null. So let's actually go and change that. Let's see what happens if we. Simply go and change that to a page. And I gotta make that smaller. Home page. Where is the CTA? There it is. Choose a page and let's choose any other page. Let's go to the blog. Sure. Okay, that's been saved and oh look at that our banner CTA. It's a foreign key
to an ID that has an ID of five It has metadata. It tells us what type of page it is. It gives us a detail URL. So if we wanted to see this URL, we would simply go to pages slash 5, which we can see at the end here. And now we have detailed information about our blog page And in fact, this one even gives us our parent information because we're not looking at the homepage, we're looking at an inner page. This one has a parent ID, homepage, so this is good for structuring your single page application. And it gives you detail U URL, uh HTML URL, title, and all that good stuff. So that's all we really need to do to enable additional fields. So now this is really cool, and if we go back to our listing page, we are going to see that in page 3, this is our homepage
We don't have the additional information that we need. So what if we needed to get all of the blog listing pages, but we needed that additional information? How do we get that from the listing page? Because as of right now, we have a problem. The problem is we are getting all of our pages, which is a total of eight, but we don't have any additional information. We just have the basic stuff. So this is good enough for creating links, but it's not good enough for creating any sort of visuals in your application. And in order to go and get any additional data, we actually have to click this link. I'm gonna append that port there. And then we can get all the extra information that we need. But on your homepage detail view, which is what we're looking at here, a home page has no parent.
Uh title, banner, title, banner, subtitle, image, all that good stuff. What if we didn't want all of this information? Right now this is this is using 13 queries. Let's refresh. 13 queries consistently in a total of three milliseconds. What if we said, you know what, we actually don't need the first published at, uh, we don't need a parent, we don't need an SEO title. We could we could actually change this in our URL. This is really, really nice actually. This is something that is relatively new in the world of web. I've been around for a long time. And this is a fantastic, fantastic idea So you type question mark fields is equal to and then you put a negative sign in front of the field that you don't want. So for instance, let's get rid of our SEO title
right there. So SEO title. There's no more SEO title. Let's get rid of the first published at. So all I'm going to do is put a comma, negative sign, first published at. Get rid of that one And so we can see that's not in there anymore. Let's also get rid of parent. Parent. There's no more parent in there. So you can see that this is actually reducing the number of queries. By telling the API to only give you data that you actually need, you can speed up your application by quite a bit. Now in this instance The uh processing time for my number of queries doesn't actually change, it's still around three milliseconds. That's two milliseconds.
A little bit better What if we wanted no fields? We could do this. And in fact, I'm going to make a video about this right after this one. We're going to go into how we can customize our views and what the API s gives us back. But just as a quick little overview, get riding getting rid of all views is simply an underscore. And if we wanted all fields This will give us all of our available fields. So there's a lot more to this. We can do a lot of stuff with our URL. All we have to do is change our URL and it will give us the data that we are telling it to give us. It automatically parses it for us, it does all the heavy lifting and all of a sudden we can do more front end work than we have to do back
end work. And in my opinion, this is why Wagtail CMS is a leader in headless CMS. I know WordPress and Drupal and all those other ones, they all have this already, but they don't make it this easy. Because if you said, hey Caleb, can you turn uh can you turn my Wagtail website into a headless CMS and uh only return certain fields? I could tell you, yeah, I can do that for you right now. It will take me six minutes. It's not going to take me an hour. It's not going to take me a day. Customizing it is super super easy. The data structure is already there. All we have to do is expose it to the API. Nice and simple. So I got a little bit distracted here, and what I'm going to do is I'm going to split what I was talking about into a different video. But the core of this video was all about making
additional fields that we have written in our custom Wagtail page, we want those to be exposed in our API. And that's exactly what we did. And remember it only took us four lines of code and then for every additional field was just one more line This has been nice and simple for us to uh actually just to put it to use immediately. It only took us a couple of minutes realistically. Now I'm going to leave this code in a git commit in the description down below If you have more questions about the API field, which we are going to tackle in future lessons, but if you have more questions right now, you can always go to docs. wagtail. io. They cover a lot of goodies in there. My name is Caleb Tallin, I'm the voice behind the video. You can also find more videos like this at learnwagtail. com. If you like this video, if you found it helpful
Feel free to click share, subscribe, or even leave a comment down below. And if you're interested in seeing the rest of the videos in this playlist, you can always click That square to the top right and that will bring you to all the other Learn Wagtail videos on YouTube. Thanks for watching and I'll see you in the next video
Import `APIField` from `wagtail.api` and add an `api_fields` list to the page model, with one `APIField` entry for each custom field. The first field takes about four lines of code, and each additional field adds another line.
Discussed at 1:34An image field returns an image ID, metadata, title, detail URL, and download URL; its detail endpoint also provides dimensions and tags. A page foreign key returns the page ID, type, metadata, detail URL, title, and—when applicable—parent information.
Discussed at 3:10Add a `fields` query parameter to the API URL and prefix fields you want to omit with a minus sign, such as `?fields=-seo_title,-first_published_at,-parent`. You can also use an underscore to request no fields or request all available fields.
Discussed at 6:17Note: 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.
Published September 19, 2026
Published July 9, 2026
Published May 20, 2026
Published April 16, 2026
Published April 1, 2026
Published March 10, 2026