Steering Council introduction
Published June 4, 2025
This video features Emma Delescolle at DjangoCon Europe 2019 in Copenhagen, Denmark.
https://2019.djangocon.eu/talks/making-your-life-hapier-with-django/
By Emma Delescolle - https://twitter.com/EmmaDelescolle
Audio glitches in this video: The first 3 videos of the conference had audio quality glitches (small sound skips), which were fixed in subsequent talks. We apologise.
Django REST Framework APIs normally require serializers, view sets, and URL registrations for each model, which can make a large API repetitive to build. The speaker presents the Schema Adapter as an admin-like layer that can automatically expose model CRUD endpoints, while still allowing customization through endpoint classes, serializers, view sets, auto-discovery, and custom actions. It also generates richer, client-specific metadata so frontends can discover relationships, fields, forms, actions, and models without hardcoding backend details, with adapters for Ember, React, Angular/Formly, JSON Schema, or custom formats.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: for lunch and that will start at 1245. So now for the first talk of this segment we have Emma Delascoll with Making Your Life APIer with Django.
Speaker 2: Thank you. Um okay. Um I'm going to wait for the slides to come on So yeah, that's great. He found a way to to pronounce the title because I honestly had no idea how to pronounce it. It looks good written down, but I was not sure how to pronounce that Okay, and full screen. Okay, so making your life happier with Django. First of all, who am I? My name is Eva. I am co-founder of a small Belgian company named Levit. Um
Speaker 2: and yeah I should is this better? Okay. Um I've had the honor to be chosen as a DSF uh individual member. Uh Not too long ago. I'm also the maintainer of these two projects, the Aeroschema Adapter that we're going to be talking about today, and Ambier CLI qualities. So making your life API. I guess you all know that we're going to be talking about APIs today. But uh first of all, what is an API? So according to uh Wikipedia, this is what an API is So in short , it is a set of clearly defined methods of communication among various components of a software.
Speaker 2: It can make development easier if it is well written. And it does not only apply to the web, although today we're mainly going to be talking about the web. So when we talk about the web and APIs, we talk about usually REST APIs. There's uh recently things like GraphQL that have um been introduced to the scene but here we're here to talk about REST APIs with Django and usually what does a REST API with Django and Django REST framework look like looks like Well it's a set of views. One set for collections where you can get and post.
Speaker 2: So for example here we have uh landpoint for products So slash API slash product you can get do a get call on that and you will get a list of products or you can do a postcall on that to create a new product. You also have a second view which is the detail view similar to Django detail view for just displaying webcap page. And on this detail view, so it's uh slash API slash product slash DID and you usually have four methods on that, get, that will give you the details of the product all the information but that is used to update the entire product so all the fields of the products
Speaker 2: patch which is used to update only certain fields of that item or delete which is uh used to be to to delete uh the item If you talk to people who like REST a lot and they want you to have what they call a RESTful API, they will also tell you that it's very important that your API is discoverable. We will come back to that uh a bit later. So why do we need REST APIs with Django project? After all, what we want to do is display web page. We we don't want APIs Well, you kind of too. You sometimes want the APIs to add uh advanced components on your page, or you want to make your data available to third-party applications.
Speaker 2: That's um usually that's been uh for a long time the first reason why people made APIs for their uh products for their website Like for example if you have a weather website and you have a basic website where you can enter a city and the website will tell you the the weather in your city, that's really nice. But if they have an API, if there's an API that's open, what you can do is you can make requests to that API and for example add the local weather to your favorite shell. And so you always know what whether it is uh it is outside without having to look through the window. This is Well people are laughing, but I know people who have done that.
Speaker 2: But more recently uh there's been other uses for uh APIs Um mobile devices have made APIs much more popular and needed because uh whether you have an Android or uh you have an iPhone These are two completely separate clients, two different clients that need to interact with the same I lost that need to interact with the same set of data and be able to retrieve the same data, update the same data, and so If you have a nice API, you will be able to use the same API with both clients. Something that is also fairly new is web frontends, JavaScript. um
Speaker 2: frameworks or libraries like React, Vue, Ember. And those are also making use of APIs. And also we want to use APIs and this client-server interaction because we know it works. We've been using that for years. Somebody else, unfortunately, I don't remember the name, but in another conference said that working with computers in programming is a bit like a pendulous. At some point at the in the 70s we had mainframe like the IBM AS400 and you had one mainframe, one big computer on the uh on the premises and everybody would have terminals, would have uh 10 clients
Speaker 2: with which they would connect to the to the server and then we we kind of went The other way and everybody had a desktop computer and you are hanging in the middle and we are going to maybe find some balance But yeah, so API with Django. So when you we talk about API with Django , we usually talk about Django REST framework. Django Rest framework is um a special place uh in the uh Django ecosystem because it is one of the only um applications that is recognized that is um uh recognized by the core team as being part of Django even if uh slightly outside.
Speaker 2: Um and right now most people would not think about using something else but in the beginning there was also Tasty Pie. So I don't know how many of you know about Tasty Pie. A few hands, yeah. Um so TCPI uh used to be uh in concurrence with uh Django Rest framework. It is built differently, it's built um similarly to some uh REST APIs for other frameworks like uh Rails And one of the reasons that it might have been popular at some point that is that it was easy to prototype things with uh it required less code
Speaker 2: and it was faster to to prototype things. So what does the code for an API with Django REST framework look like? It looks like this. So for starters you usually don't skip to the next slide. You usually have uh for each model you usually have to uh create a serializer. and tell uh tell it what model you're serializing, what fields you have, this is the minimal information. You also need uh view set. Well well you don't need a view set, this is a way to do it. You could have uh a set of different distinct views but one way to do it the minimal way is to have a view set and provide that view set with a query set and a serializer
Speaker 2: And then uh you are left with uh registering that uh view set in the URLs. If we want to just uh for information's sake compare to uh what you would have been doing with uh TestiPy, with TestiPy you would just have had to declare a resource per model and then register that resource in the URLs. It's less code, but it's also sometimes perceived as a bit more magic and less flexible. But yeah, I love um Django Rest framework, but one day uh I found myself in the position of having to write a new application.
Speaker 2: This application has about 15 models that I took the time to write and to prepare. And we needed to create an API because this was an API-based application And I really didn't want to write 50 serializers, 50 view sets, 50 URLs. I'm a bit lazy that way, so I started thinking, well What if I could do that with a what if I could just get away with Django admin I mean with Django admin you want to create an admin for a model, all you have to do is to register the that model. You can do uh either you can create a class with uh um
Speaker 2: uh decorator or you can uh just register directly the model just don't say anything this is a minimal thing to do one other great thing about the admin is that I don't have to create a different URL for each model that I want to expose I just need to expose the URL for the admin and everything is done. And if I'm really being really, really lazy, I could just import the the models module for my application and just uh loop through all the the things it exposes, look if it's a model and just register that and and don't do anything else. That's that's three line of code. I would I would be really happy to be able to do that. And so this is how the Euroschema Adapter uh started.
Speaker 2: The ideas for uh the schema adapter started. I wanted to be able to uh register to create some APIs as fast as I would have been able to create some admins. And so this is the code that you would need to write to uh create a Django RS framework API with the schema adapter. works uh very similarly to the admin as you can register a model either by using a decorator or on a special class or you can just register uh model directly on the the router and you just need to add uh this router once in the URLs and then you have A fully working basic API that will do CRUD
Speaker 2: for all those models. No customizations, all fields are exposed, everything is writable. This is not what you want for production ap for for production application, but it can get you started really quickly. Now of course fast prototyping is nice but you need to be able to customize that This was one of the problems I I went mentioned with TestDPI. Apparently people were not seeing clearly how they how to customize their thing. It was easier to do with the Django Rest framework But so here with um the endpoint class that I've been using to to register my my endpoints, I can do some customizations too. And that customization looks a lot like
Speaker 2: what it would be uh looking with uh admin class so we're familiar with that. It also uses the same terms as um the as JackGor 's framework uses in some of its classes. But yes, what this endpoint class, it's it's not just that, it also hides uh some factories. So um Uh what you can do is because when you look at at a serializer, for example, when you want to write a Django Rest framework serializer, the first thing you have to say is, hey, this is a serializer for that model, I want to expose those fields. And you have those details that are a bit uh redundant sometimes, that can feel a bit redundant, and that could be replaced by a factory.
Speaker 2: So for example here to create a nested serializer I'm using a serializer factory that just takes the models and um the the main serializer does not have this information of what model it is for um what field it exposes because this is this factory is going to be fed into my endpoint class Um I think I skipped a slide. Um Yeah, here in my product endpoint I've got a base serializer. This is going to be fed into a factory that's going to fill in everything that I did not bother to fill in myself. Um so this um
Speaker 2: this endpoint class is is not is not really magic. Um it's just a wrapper around uh Django Rest framework and a series of factories and those factories do very basic things like filling in the blanks that I was too lazy to fill in myself. There is this base serializer. There's also a base view set that you can provide to the endpoint classes. And base viewsets are work with the same principle as base serializers. Those are view sets that I wanted to customize. I wanted to customize methods on the view set I wanted to do something special, but I didn't want to bother to fill in the information that
Speaker 2: I thought were obvious like uh the query set or the serializer I was going to be using. And also, um fast prototyping. Uh for fast prototyping I was really um Looking forward to not having to write one URL per model that I wanted to expose because I still had those 50 models to that I wanted to expose. So I wanted to have something where I could just stick one URL for the for my API and then everything else would be uh Done automatically for me. So since the admin was already doing that, I decided that I wanted to do the same as the admin
Speaker 2: and use uh the auto discover the Django auto-discovery um processes So if you create in your application an endpoints. py file, uh it will be automatically loaded and uh register all your uh endpoints just uh as you would if you created an admin. py file and every admin class that is in there is going to get automatically added to your admin But if remember we talked earlier about discoverability. Thus what what were we trying to do when I was creating this application?
Speaker 2: The this API-based application, the idea was to have a 10 client that didn't know anything about my application, just knew how to log in and to access the API. Um and I wanted this client to be able to do everything, so my API needed to be discoverable. And um So I I was I I needed to be able to to expose some uh some more information. Um and one way Usually when people talk about discoverability for an API, what's what the the kind of things that they're expecting to see is this. If you look here and you see for the category field We don't have just an ID, we have a full URL to be able to
Speaker 2: access the API for that category. And if we click on that, well we will see the JSON for the the category that this product belongs to. Which is nice, it's very readable for humans. Now on the other side of the screen You have another ex example which is a too many relationship. It could be one too many, many, too many, it doesn't matter. And we see here that we're starting to to have a bit of a problem. It's starting to be quite verbose because we have These five links to products. The links are basically the same. It's just one thing that changes. It's the ID. So maybe we could have something different like having
Speaker 2: some information about that field, that's the address for this API is slash API V1 slash category slash products and then just have the ID Which you can have uh in your Django Rest framework API if you just uh choose a regular uh relationship field and not a hyperlink relationship field And this kind of information, there's already uh already a place to get it. In Django Rest framework, there is this thing that's called a metadata class. And the metadata class is what um what writes the information that you will see when you do an options call to your uh endpoint uh to to the base URL of your endpoint
Speaker 2: So here this is the the information we get for the products and as you can see we have some names uh description what it's uh accept what it births We also have at the bottom of the screen a list of actions. And for each of those actions we have a list of fields that didn't fit on the screen. But the field I wanted to show is this one. This one I wanted to show this field to you because unfortunately I don't find that really useful. This uh tells me that my field is the field for category that is of type shield. Wow This is a surprise. It's it's it's a field, okay? And well, at least I know that it's required, that it's not read-only, and I have the label, but
Speaker 2: I don't really have much useful information. What what is this field? What does it represent? Can I can I put some string in there? Can should I put some integer? What what is it Um so I wanted to to do more, I wanted to expose more data, so I uh started writing something else. And right about now I have to make this disclaimer. My personal framework, front-end framework of choice is Amber. So There are going to be some mentions of Ember. js in the next few slides. If you don't like Ember, it's okay. What I'm going to say is uh Valid for any other framework is just that I have concrete examples uh with Amber
Speaker 2: and not with uh other frameworks Uh so um as I was saying I wanted to write to create some some metadata and I wanted to be able to expose some different data in different circumstances So uh Dira Schema Adapter uh provides uh this thing, this is a metadata class And this metadata class can use different adapters and you can have a default adapter but from the command line or from different URLs or things. you can decide to uh expose different types of the metadata at the same time. So for example, you could be exposing some metadata for an Amber application, but you could also be At the same time with a different URL
Speaker 2: be exposing some metadata for React application. And um so since um This data here is some metadata for Amber, which is a full MVC framework, so it has this notion of models and foreign keys and relationship. I can uh provide this data and I can say, hey, this is not just a field, the widget for this field should be a foreign key. I also have the extra information of this related model and the name of the model. So by putting the base API address plus the name of the model together Amber is going to be able to get a list of categories. So if I want
Speaker 2: to, for example, provide a drop-down of categories, the front-end application would know where to get the list of categories. It needs to populate the drop-down. Um since um it also knows that it's a foreign key, when it's going to get the JSON with the data for that record, it's going to see that the category ID is one. And so it knows that in that drop down the category to be selected is the one with IB1. Um so once again back to the reason I started this application, Service Schema Adapter. is that they want an API-based application.
Speaker 2: So exposing models with CRUD functionalities is great, but that's not an application. Usually you need to do something else For example, if you have an invoice you want uh in the list of invoice you might want to have a button next to an invoice to be able to download a PDF for that invoice. Or you want to have another button next to on that line that you can click and say, hey, my customer paid that invoice. Please mark it as paid. And so um we need some some way to expose that and as we have seen uh on uh the previous screen Uh the default metadata for uh Django Risk frameworks already
Speaker 2: already tells you about some actions, but it only gives you the actions for the current URL that you are using. Um no, there's only a limited set of methods that you can do on a URL. You can do options, get, post, put, patch. Uh if if I have five different things, uh first of all I don't have enough methods, and second of all it would not be a great uh way To just do a a different method to print an invoice. I would like to have a specific URL to print that invoice But then this is not discoverable in the basic metadata. So I need some other way to expose that So uh once again, using uh the DRIS schema adapter metadata
Speaker 2: class and uh your adapter of choice, you can decide to expose some more methods And how do you uh tell uh Django Rest framework and their schema adapter that those methods need to be exposed? Well, there are two ways to do that You can either just uh pass it a dictionary with uh the available actions and all the information you want to uh give about those actions. Or you can use some decorators on some of the methods that you will be writing either on the endpoint or on the view set And for example, here we have a pay method that is decorated. I am sorry about the color this uh this gray uh it might not be readable for everybody.
Speaker 2: But there is a decorator on top of the of the method that just says, hey, this is a custom action, uh, here is the text I want. um to use and uh here is the um the method it it needs to use so method as imposed And um so their schema adapter is going to be looking through all your endpoints and looking for those decorators and thinking, oh Here's the collection of actions that you can do for these invoices. And so it's going to provide a list of available actions. So your clients can, for example, put a series of buttons next to each invoice. Um of course
Speaker 2: as I as I said an adapter that has been built for Amber. There are some other default adapters. I'm going to start by talking about the JSON API adapter. If you've never heard of it, JSON API is this thing that seems to be great. It does exactly what I want. It is uh um and uh it's not JSON API, it's JSON schema. JSON API is something totally different. I'm sorry. So JSON schema um is this thing great. That's supposed to be uh um a way to describe fields. And there are a lot of libraries that claim to be using uh JSON schema. Unfortunately, JSON schema is uh really small by itself and it doesn't uh have things like for
Speaker 2: ring keys and things like that So a lot of libraries that claim to be using JSON schema use JSON schema as a base, but they all extend it with their own extension, and all the extensions are different and usually not compatible So this is why there is an adapter for uh basic uh JSON schema, but there's also another adapter that is provided That is for uh some uh React uh JSON schema because there is a library in React that uses JSON schema which It's not the basic JSON scheme, I'd expect some other data. We also have an adapter for Angular and the Formly library that allows you to build forms
Speaker 2: We of course have an Amber adapter which is the most fully fledged adapter that takes all the information that is available from your endpoints, from your view set, serializers. all the fields, all the actions that are possible. It can do lists, it can do forms, it can do uh actions, uh wizards, everything. But this is if you are not using Amber, this is probably not what you want. So you can also uh build your own adapters and decide what information you want to provide and how you want to provide it. There is a base adapter that you can extend and you can uh Select the everything that you want to expose or and how you want to expose it.
Speaker 2: Um but yes Since I opened the Pandora box and started talking about Amber , there are other things that could be useful for my front-end application. Um and this is valid for Amber, this is valid if you're doing a GTK client, it is valid for something. So Amber is a full MVC framework, so it has this notion of model A model for my client, what is the model for my client? It's not going to connect directly to a database, it's going to connect to an API. The model for my client is a mirror of the serializer for my endpoint. It just says the list of fields for which kind of models. So this is something that
Speaker 2: I already know, we already know our backend. So this is also something, this is the second part of their schema adapter. There's an exporter application that can be used to export uh some information. So in this case It is exporting a very ugly uh JS uh model for um for uh This is for segment, for serum segment. It is uh exporting uh some information and I'm going to skip because I am running late and so I will not have time for questions. And so this is for example an example of a form that can be completely rendered. just by extracting information from an API. The
Speaker 2: front end that is rendering this application has absolutely no information about the back end, it knows how to log in. and how to get the information from the API and it is able to render this complex form just with that information. Since I'm running a bit over time, uh if you have some more questions and you want some more information Feel free to find me in the hallways or come find me at the sprints. And I will be publishing the link to the um to these slides with uh the links at the end to the library and some examples Thank you.
An API is a set of clearly defined methods for communication between software components. When well designed, it makes development easier and can be used beyond the web.
Discussed at 0:58APIs can support advanced web components, expose data to third-party applications, and let mobile apps or JavaScript front ends use the same data and operations.
Discussed at 3:22The Django REST Framework Schema Adapter lets you register models much like Django admin models, add one router URL, and automatically get a basic CRUD API for them. It exposes all fields and makes them writable by default, so it is intended mainly for fast prototyping.
Discussed at 11:10You can configure an endpoint class and provide custom serializers or view sets, while factories fill in routine details such as the model, fields, serializer, and query set. This keeps the convenience of generated APIs while allowing custom methods and behavior.
Discussed at 11:57The Schema Adapter supplies metadata adapters that expose more useful information than Django REST Framework's default metadata, such as foreign-key widgets, related models, and URLs from which choices can be loaded. A front end can use that information to populate fields and select the correct related record without hard-coded backend knowledge.
Discussed at 20:29You can declare available actions in a dictionary or decorate methods on an endpoint or view set. The adapter discovers those actions and includes their labels and HTTP methods in the metadata, allowing clients to render appropriate buttons or controls.
Discussed at 23:47It includes adapters for basic JSON Schema, React JSON Schema, Angular Formly, and Ember, and it provides a base adapter so developers can create their own format. The Ember adapter is the most complete and can describe fields, forms, lists, actions, and wizards.
Discussed at 25:49Note: 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 June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025