Making your life (h)APIer with Django

This video features Emma Delescolle at DjangoCon Europe 2019 in Copenhagen, Denmark.

Making your life (h)APIer with Django
0:30:35
Published April 23, 2019
1,247 views

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.

Summary

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.

Key takeaways

  • Django REST Framework APIs commonly require repetitive serializers, view sets, and URL configuration for every model.
  • The Schema Adapter can register models in an admin-like way and automatically provide basic CRUD endpoints.
  • Endpoint classes, base serializers, and base view sets preserve customization while filling in repetitive configuration.
  • Auto-discovered endpoint modules let one API URL expose many registered models.
  • Metadata adapters describe relationships, widgets, models, forms, and custom actions so clients can build interfaces without knowing the backend in advance.
  • The library supports several frontend-oriented metadata formats and allows developers to create their own adapters.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Introduction and API Fundamentals Emma introduces herself and defines APIs before narrowing the talk to REST APIs with Django.
  2. 1:49 REST APIs with Django The talk covers collection and detail endpoints, CRUD operations, and the importance of API discoverability.
  3. 3:22 Why Django Projects Need APIs The speaker explains API use cases including advanced web components, third-party integrations, mobile clients, and JavaScript frontends.
  4. 6:30 Django REST Framework The talk compares Django REST framework with TastyPie and outlines the typical serializer, view set, and URL setup.
  5. 9:38 The Schema Adapter The speaker describes creating an API quickly from models, inspired by the simplicity of Django admin.
  6. 11:57 API Customization The schema adapter's endpoint classes and factories reduce boilerplate while still allowing custom serializers and view sets.
  7. 16:35 Discoverable API Metadata The talk explains how metadata can describe relationships and provide clients with more useful information than basic field types.
  8. 19:44 Frontend Metadata Adapters The speaker demonstrates adapters for Ember and other frontend frameworks that use API metadata to build models and form controls.
  9. 22:47 Custom API Actions The talk shows how to expose discoverable actions such as marking invoices as paid or downloading invoice PDFs.
  10. 25:49 Schema Formats and Custom Adapters The speaker reviews JSON Schema, React, Angular, and Ember adapters, and explains how to build a custom adapter.
  11. 28:10 Generated Frontend Models and Forms The talk concludes with exporting frontend models and rendering complex forms from API information without backend-specific knowledge.

Transcript

4,479 words · auto-generated Show

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

0:00

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.

0:12

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

0:58

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.

1:49

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.

2:35

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

3:22

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.

4:10

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.

4:58

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

5:44

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

6:30

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.

7:18

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

8:04

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

8:53

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.

9:38

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

10:24

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.

11:10

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

11:57

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

12:43

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.

13:33

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

14:18

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

15:04

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

15:50

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?

16:35

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

17:21

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

18:07

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

18:53

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

19:44

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

20:29

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

21:16

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

22:01

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.

22:47

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

23:33

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

24:19

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.

25:04

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

25:49

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

26:36

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

27:22

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.

28:10

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

28:56

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

29:42

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.

Questions this talk answers

What is an API, and what does it do?

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:58

Why use a REST API in a Django project?

APIs 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:22

How can I quickly create a CRUD API for Django models?

The 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:10

How can I customize an automatically generated Django REST API?

You 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:57

How can a REST API describe its fields and relationships to a front end?

The 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:29

How can I expose custom actions like paying an invoice in a Django REST API?

You 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:47

Which front-end metadata formats and adapters does the Django REST Framework Schema Adapter support?

It 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:49

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 by Emma Delescolle

More videos from DjangoCon Europe