Build a Rest API with Django Rest Framework

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody and welcome back to the channel in this video what we're going to do is cover django and specifically django rest framework we're gonna learn exactly how we can build a rest api with django now for this tutorial i do expect you to know two things i do expect you to know the basics of python and also the basics of a rest api now here in this tutorial even though we're building a rest api i'm not going to be explaining you know what a rest api is so i do expect you to know kind of the basic knowledge of the server uh model the server client model which is requests and responses i also do expect you to know you know what a post put put delete get requests are so that's really what i expect you know however you do not need to know any django so let's go ahead and start looking at some of the installations that we need to do of course we need python installed on our local machine so for for some reason if you don't have it installed just go to python.org downloads and go ahead and install python now once you install python we need to get django installed on our local machine as well in order to do this open up your terminal or your command prompt and what you're going to do is you're going to execute the command python3 python and then dash m pip and install django and what this is going to do is install django on your local machine now i already did this i'm not going to do it again but to test that you actually got it installed correctly you can just do django admin and if you get all of the different commands you can see here that it's working a-okay so now what we can do actually is execute this command which is start project so over here what we can do is we can do a django admin django dot admin and i'm in my desktop directory you can move into whatever directory you want this project to be in django admin start project and you can give this project a name i'm going to call it books so let's go ahead and create that and now what we can do is we can move into that directory and then you can open it up in whatever code editor instance that you want i'm going to choose vs code for this so i'm going to say code dots to open it manually for me or automatically and as you can see here let me close this let's go here let's try this again code dot and as you can see we have this right over here we have this boilerplate uh project right here we'll talk about a lot of these things a little bit later don't worry but for now what we're going to do is we are going to go over here and we're going to create a new application so you might be thinking didn't we just do that well no we created a project in a django you can create a project and a project can have multiple apps so you can think of the project itself as the root application and then the apps themselves as kind of sub applications that can interact with one another so we can actually have multiple apps that are inside of the same project unless they're gonna kind of have the same urls as well so let's go ahead and create a new project so we're gonna go here and we're gonna create a brand new project and we're gonna utilize this manage.pi to do that and sorry we're going to create a new app not a project so we're going to say python.3 manage.pi and then what we're going to do is start app and then we're going to call this i don't know let's call it book api let me just double check that that's exactly what i called it in my notes let's see here book yeah i call the book api so let's go here book underscore api and what that should do is create a new app right over here now that we have created our application the first django feature that i want to talk about are models so i am inside of the books underscore api directory and then in here i'm in the models.pi file and you can see we have this boilerplate so from django.db we're importing models now what is a model well we can kind of get a hint from this line right over here we're importing it from django.db so a model is going to interact with our database in some way now specifically what a model is going to do is translate how our data is going to look from python code to whatever code your database understands so for example if you use a sql database which we will be using in this tutorial it is going to translate that into sql code so for example let's say our books have a title our books have a number of pages these are all the different properties that we have number of pages let's say we have a quantity and we also have let's say one more field let's say published date so published date now this right here is going to be how the books are going to be structured now in order to create this structure inside of our database we're going to need to create some sort of sql command something like maybe create table books and then we need to define the properties or columns inside of each table so we say title and then varchar maybe 255 something like that now this is pretty annoying and we actually don't want to do this inside of our api instead what we probably want to do is define a model that is going to define the structure of our data and then django is somehow going to interpret and understand that model and translate that model into sql code once it translates that model to sql code it can go ahead and execute that sql code in our database and create that table that way we never have to touch any sql code instead we are just creating models so let's go ahead and create our very first book model now inside of django a uh model is a class we're going to say class book and then what we're going to do is we're going to pass in models that we get from right over here models dot model and this is going to give our class the ability to inherit certain properties that only models have now in here what we're going to do is we're going to start defining the properties of our book so we're going to say title and that's going to be equal to models dot char field essentially what this is saying is that this title over here is going to be a string or a character field now we can do the same thing we can say number of books or number of pages this is going to be an integer so we can say models.int field we can also do publish dates this can be models dot date field how cool is that last thing we can do is quantity and we can say models dot we can also have this be an integer field now inside of the character field we have to supply it with the max length so let's say a max length of a hundred that's really all we have to do now one other thing we can do is also define the underscore underscore srt function over here and for this what we can do is just return self dot title so this is just basically going to if we ever want to see this data inside of a table we're going to see the title in order to identify the book that we want instead of other fields that's pretty much all it's doing not that important honestly so now that we have defined our model what i want to do is of course hit some sort of endpoint so i want to hit i don't know in our django api we want to hit this endpoint over here maybe something like slash books slash list and i want to get an array of all of our books so how am i going to do that can i do that with the model well not quite what we need to now do is work with views so we're going to go over here we're going to go to our view and a view is either a class or a function that is going to return data for a specific endpoint so the view is responsible for all of the logic to create and return the data so again let's say what i want to do is i want to return a list of all of our books so how do we do that well what we can do here is create a book view so you can see here books list and in here what we can do is get the incoming request as a parameter and then here is where we can actually perform all of the logic to get our books so what we need to do is we need to somehow interact with our database to get all of the books so how do we do that well we just created this model right over here now not only is this model going to be responsible for creating our table but we can also use this class right here in order to query or mutate our data so let's go ahead and import that so we're going to say from we're going to say from books api dot models we are going to import the book class now right in here the first thing that we need to do is well get our books so let's say books and that is going to be equal to book now each uh each book inside of this database is going to be an object so what we want to do is we want to get all of the objects so we're going to say objects and then we want to get them all not just one of them so book.objects.all so this is what we are going to execute now this is going to return a data type known as complex data so this isn't really python code this is complex data so then what we need to do is we need to convert this into python code so python data structures like lists and dictionaries so over here i'm just going to have this temporary variable and i'm going to call it books python we're going to change this later but this is books in the python data structure so over here what we're going to do is we're going to say list so we're going to convert all of the books to a list and we're going to get the values of each list so we're going to say values like that so that's the thing that we're going to do so now over here this is python data structure so python data structure so ds the last thing that we need to do is we need to convert this python data structure into json because the way that the web interacts with the servers is through json that's how things are communicated so what we can do here is we can actually import something from django so from django.http we can import something called jsonresponse so what we can do here is actually return json response and we can pass in a python dictionary so over here we pass in a dictionary we say books and over here might as well even change this to snake case like so you can say books and then over here we give it the books in the python data structures and that's what we have to do every single time we get it as complex data we converted to python data structures and then we converted to json now this is actually a huge step there's a lot of different things that we have to do we're going to look at how we can automate this a little bit later but for now this is how we are going to do it so this is the view so this is going to be again responsible for actually returning our data but this doesn't really solve the issue i want to be able to hit this end point and this endpoint should call this view right over here so how do we do that well we're going to do that inside of the urls.pi file so i'm inside the project directory so the books directory and you can see that we have this urls.pi file and this is actually where we are going to define all of the urls in our application so what i'm going to do is i'm going to go ahead and copy this and inside of the app so inside of this app that we just created where is it right here what i am going to do is i am going to create a new file called urls.pi i'm going to go ahead and paste that in there and i am going to get rid of all the comments and i'm going to get rid of this so let's quickly look over here and see what's going on so over here we're defining the path which is slash admin and then we have this thing that's going on here so basically what's happening is if we go to slash admin what's gonna happen is it's going to call whatever this is and eventually what this is is going to render some sort of web page for us so what we want to do is have the ability to call slash book slash list and it should call this view right over here to return our data so very simply over here inside of the inside of the books api what we can do is we can say path and what i'm going to do is instead of saying slash book slash list i'm just going to say list and i'll show you why later but once we hit this path what i want to do is call so what i want to do is i want to call this view right over here so over here we're going to need to import that view so we're going to say from books api dot view we are going to import and what are we going to import we're going to import that book list function and over here book list so whenever we hit this list path we're going to call this function and return whatever data that this is returning so now what we need to do is actually connect this to the urls in the project so over here what we can do is we can say path and this is where we're going to say books so books right over here and then we're gonna do we're gonna import something else called include and then we're going to include all of the urls inside of the books underscore app directory so we're going to say include and then we're going to say book underscore app dot urls so what's going on here so whenever we hit the books directory so whenever we hit this directory it is going to go over here to the books api and it's going to look at the paths here so if we go slash book it's going to go look at the paths in here oh my goodness get out of here so if we go to slash books it's going to look at the paths in here because this is what we included and then it's going to see okay what other paths do we have if we then hit slash book slash list then what it's going to do is going to call this function and return this data so i hope that makes sense enough of the talk let's actually give this a quick go now one thing that we also need to do is we need to go to the settings.pi file and inside of the settings.pi file we need to go to our installed apps and we need to uh we'll place this app into one of the installed apps in our project so over here we can just say books or book api book underscore api all right so let's actually go ahead and give this a quick go i'm gonna go ahead and open up my terminal and in order to run my server what we need to execute is python 3 and then we're going to execute python 3 and then manage dot pi and we're going to say run server now this isn't going to work right away as you can see here we're having some issues so over here okay i have some syntax issues let's go over to our model and this should be sorry apologies for that it should be book stop ma dole not mo model apologies for that i hope you guys uh caught that let's go to our view you can see now we have some really good syntax highlighting so now i'm going to do is i'm going to go ahead and run it and you can see that it it is indeed running so it's running on this port right here so what i'm going to do is actually open up this application and you can see here that it's not really working the way that i thought it would so it says here that this page is not found so django tried these url patterns let's go ahead and try slash books so slash books slash list so right now we're getting an error so okay so this is this is actually working the way that we wanted to so when we go to slash book slash list we're getting this error saying that hey um this this table doesn't exist which doesn't really make sense because well i thought we created this model well creating the model is not enough what we actually need to do is we need to somehow migrate this model into sql code so the typical process of this is we create a migration a migration is basically interpreting this and creating sql code and it's going to create the sql code in a specific file and then inside of this file what it's going to do is it's going to take the file and execute that into sql code so let's go ahead and do that right now so i'm going to go ahead and do control c click out of here and i'm going to say python3 manage.pi and we're going to make migrations we're going to make a migration let's go ahead and do that you can see here that we made this migration so now what we need to do is actually perform the migration so we can actually perform that sql code so let's do python 3 managed of pi we're going to say migrate so now we perform the migration and now our database actually has that table so now let's go ahead and run our server again let's go over here and now voila you can see that we're getting our data how cool is that now that we got that working let's actually look at a potential issue that we're facing at the moment so right now inside of our view file let's take a look at the process that we have to do in order to actually send a valid response we have to get the complex data confirm it and convert it into python data structures and then convert it into json and then send it as a response this is a very cumbersome process that i would rather not do over and over again instead what i want is to get django to kind of do this step for me now what are we doing here we're just changing the format of our data we're changing the structure of our data now that is known in the world of programming as serialization now inside of rest framework and this is where we're going to actually start using django rest framework up until now we haven't been using it but inside of the rest framework package there's actually a built-in serializer that can do all of these steps under the hood so let's actually go ahead and get rest framework installed inside of our django application and in order to do that it's actually a really easy step all we have to do is to go to settings then inside of settings just simply state rest underscore framework that's really all it is that we have to do so now what we can do is utilize this rest framework package to create a serializer so what i'm going to do is i'm going to create a serializer.pi file and this is where we are going to create our serializer so remember the serializer is the thing that's going to do the conversion of the data now at the end of the day we have to tell our serializer what we want our data to be converted to which is of course going to be json but we need to tell it the structure of our json code so let's go ahead and do that right now so in order to do this we're going to need to create a serializer so let's go here and we're going to import something from django rest framework so over here we're going to say from rest framework we're going to import serializers so that is what we are going to be importing so now over here we can actually create a serializer i'm going to call this book serializer and i'm going to have it inherent serializer dot serializer so this is just another class that it's going to inherit from now in here we're going to define the structure of the data that we want in our json so we're going to say id and this is going to be an integer field and we're going to get that from let's get rid of this it's going to be serializers dot integer field and you might be thinking well didn't we just define the structure of our books inside of the model well this is defining it inside of the sql database this is going to be defining it inside of our json response now you might think that this is a little bit redundant why are you doing the same exact thing and to be honest i agree with you it is redundant and we're going to look at a better way of doing this a little bit later but for now let's just do it this way so we're going to say the title of the book that's going to be serializers dot chart field and let's actually go ahead and copy the rest here we're going to say number of pages that's going to be serializer.integer field this is also going to be serializer.datefield and over here serializers. field that's really all we need to do to create our serializer now inside of the view what we can actually utilize is the serializer to perform all of these tasks for us so let's go ahead and import that serializer so from books api dot serializer we're going to import the book serializer and now instead of doing this step what we can do here is is just basically pass in this data into this books serializer and we can actually give it assign it to the variable serializer we can call this whatever it is that we want but we can do this instead so you can say book serializer and what we're going to do is we're going to pass in the books that we got from our database so we're going to say books we're also going to say mini equal to true because this is going to return to us a mini a list of objects and so what we want to do here is want to say that yes we want you to serialize many different objects into json so that's the thing that we want to do and so this is actually going to return to us json so now what we need to do is just return the response and we don't want to return a json response because this is already in json so in order to just return a normal response what we can do here is from restframework.response we can import response and then at the very end here what we can do is just return that response so we can say return and then we can say response dot so we can say response we can pass in the serializer dot data so this over here is how we access the data inside of the serializer so that's really all it is that we need to do and i believe this should be it this should work so this still should give us an empty array however the structure of this page will change a little bit if this works okay so we are getting some sort of error so it says here not set on response okay so what did we do here so we did rest framework dot response and we are returning response.serializer so response serializer.data so i assume this this seems okay i'm not really sure why that's not working uh books here for our data okay we're getting all of them so what's the error again here so we're getting an assertion oh okay i know exactly what the error is so what we're missing now is a decorator so because now what we're utilizing is rest framework we need to specifically say is this going to be a get request or a post request or a delete request or a whatever request in order to do this we need to import a decorator from restframework.decorators we're going to import a decorator called api view now this api view what we can do is on top of the function we can we can call it like so and then in here we can supply it with array with all of the different methods that we want to execute in this case it's really just a get request so now if you try to make this request again you can see that we get this really cool interface over here so we get this and we can actually utilize this interface in order to get post and delete things now you can see here at the end of the day what we're getting back is an empty array so that's the data that we are getting back but we're getting this cool interface when you're utilizing it inside of the web so that's really all it is that we need to do in order to start well getting going with serializers so now let's actually start creating some other endpoints like a post endpoint where we can create books as well as maybe you know a put endpoint where we can update books delete books etc let's go ahead and do that all right now that we created this get request let's actually create a post request which will give us the ability to create books now what we need to do first is think about the end point that we want to hit right now when we want to hit this right over here this view we hit the endpoint slash books slash list and this is going to hit this view and return this data now what endpoint do we want to hit to um to add a book now we could also hit this but change the verb to post or i think it actually makes more sense to just hit slash books with a verb of post so that's exactly what we're gonna do now because we're gonna do that we're going to need to create a new function for this so let's create book creates we're going to create a function called book create this is going to take the incoming request and now what we need to do is we need to actually grab the data that the user is going to send us so remember this is going to be a post request we're creating data a book a user wants to create a book so the user needs to provide us the book data now they're going to provide us inside of the request body so once we grab the request body that format is going to be in json now we need to convert that from json to complex data in order to insert it inside of our database so what we need to do is somehow serialize it the other way around so typically we have been serializing it from complex data to json but now we need to serialize it from json to complex data luckily this book serializer can do that for us so let's go ahead and do it right now so what we're going to say here is serializer serializer if i can spell it correctly there we go serializer and then we're going to say book serializer and instead of providing the data like this what we're going to say is data and then we're going to pass it the request body so we can access the request body from request dot data that's really all it is that we have to do now by saying data like this it knows it needs to serialize from json to complex data hope that makes sense so now that we're done that that's pretty much all that we need to do but we need to actually check that the data that we got is a valid remember the serializer has a specific data structure right over here it needs to have a title number of pages published date and quantity now the issue that we're facing at the moment is that the user is supplying us the data so they could supply us with some invalid data maybe they can supply us with some properties that don't exist or maybe some of the data types are incorrect so we need to validate if the data is actually valid before we add it inside of our database so to do that what we can say here is serializer dot is valid and then over here if it is valid and we should have an if statement here so if the serializer is valid then what we're going to do is save it to our database so we can do serializer.save to do that we can also return a response so we can say response serializer.data now else what we can do is very simply just return return another response but just with the serializer errors so we're going to say serializer dot errors now one thing that we need to do here is also define the decorator with the post request and so that's looking good but now we need to go into our urls and inside of our urls we have to specify another path now this is going to be just to slash books which is covered inside of our root urls file so over here we're just going to say just uh empty empty string and then in here we're going to import the book create and pass in book underscore create like that all right that's really all it is that we need to do so now there's one last thing that we need we need to go to the serializer and we need to create a create method this is the method that's going to be called in order to create a book in our database so we're going to say create we're going to say self and data and now what we're going to do is we're going to return we need to import the model so from books api dot models we need to import that book model and so over here what we're going to do is we're going to do book dot and then dot objects dot create and we're going to pass in the data that automatically is going to be passed in by django like so that's really all it is that we need to do so now let's go over here so let's go to slash books which i'm at right now actually let's go over here to slash books like that let's refresh so you can see here now we have this content right here so in here we need to supply it with some json code so we can supply it with a title a title and let's give it a title of um what's a good book harry potter so you spell potter potter i think i'm not sure i've never read any for books uh let's also hear number of pages number of pages let's say 300. let's also grab the publish date let's say 2021 0101 or whatever 10 doesn't matter and then the last thing we need is the quantity and then let's say that this is 400 or something like that i'm going to go ahead and copy this just in case now i'm going to go ahead and click on this post now we're getting an error so we're getting this error right over here saying that this field is required and it really shouldn't it should be auto generated for us so what we can do here is we can just very simply say here read only and we can say that's equal to true the orm should handle creating the id for us so let's go ahead and paste that in again i'm gonna go ahead and post this and now you can see that we have just created our very first record so now if we go to slash list you can see we have this right over here how wonderful is that all right so so far we have created two endpoints one to slash book which is a post request which will allow us to create a book i want to slash book slash list and this will allow us to get an array of all of the books i now want to create this other endpoint slash book slash a dynamic id so whatever the id of a book is we can actually pass that in so slash books slash one and what this will allow us to do is get that specific book and not only get that specific book we're going to use this endpoint to also update that specific book as well as delete that specific book so let's take a look at how we're going to do that so in order to do that we're going to create a new view so we're going to say def book i'm going to call this book because it's going to be doing multiple different things so let's might as well just leave it generic now this is going to take in the request as well as the primary key so once we pass in that key that primary key like so so by the way a primary key is going to be the the id that is located inside of the database so you can just think of it as an id now once we hit the end point slash book slash one that pk right over here is going to be one so we're going to be able to access it inside of this function so now what do we want to do well let's actually begin with the get request so we're going to need to go over here grab our decorator we're going to have to post that in there now remember we're going to have either a get request a put request or a delete request so if we want to you know run the logic for getting a specific book what we need to do is we need to check that okay you hit this method you hit this endpoint but the request method is equal to get so over here what we can say is if request dot method equals get then we want to run certain logic so the first thing that we want to do is we want to get the book so we can say book dot object and then we want to say dot get and we can actually supply it with the primary key so this is what we have to do to actually just get one specific book remember this is going to be in complex data so we need to serialize it so let's go over here say serializer and then over here inside of the serializer we're just going to say book serializer and then we're going to supply it with that book so let's go ahead and supply with the book and we don't have to supply it with many true because there's only one one object and then the last thing we need to do is actually return it so let's go ahead over here and return response and we can say serializer dot data so that's really all you have to do we'll worry about the put and delete a little bit later but now what i want to do is i want to go over here to our urls and i want to create a new path now this one is going to be a little bit more tricky because it's going to be a dynamic path so it's going to be depending on whatever our id is so how in the world are we going to do that well relatively easily all we have to do is specify the path and then in here to specify that it's dynamic we do these um triangle braces we first define the type and then we define the name which is going to be p k primary key and then of course what we're going to need to do is define the view that we want to hit and this is going to be book so that's pretty much it that's all it is that we need to do we can actually get rid of this as well so let's actually go ahead and try to hit this end point so i'm gonna go ahead and copy this i'm gonna create another uh another uh entity book entity so i'm gonna go to slash books i'm gonna paste this in let's get rid of the id and let's change this to um bad blood let's change it to 200 we'll leave the rest the same let's go ahead and post this and now if we go to our list we have two so now what i'm going to do is i'm going to go to slash books slash one now you can see that i'm only getting this right over here i'm also getting some put request stuff however we haven't done the logic for that either we also have this delete request that we can accomplish now right now we're using this interface but you can actually use a real client for this so you can use something like postman or your real application whether it's a react view or angular app but this is just a really cool interface that we can use to test that everything works so now let's go ahead and do the exact same thing but for the put requests as well as for the delete requests so let's go to our views and inside of here inside of our views we need to create another if statement so now what we need to do is we need to check if it's a put request so we're going to say if request dot method equals put then we want to run the update logic so what we can do here is we first need to grab the book that we want to update so let's go ahead and do that and it seems as though that this is going to be something that we do for almost every single request so maybe what we can do here is just put that at the very top because it seems like we're doing it over and over again so we need to grab the book that we want to update so we have to find it in our database and then what we need to do is well now we need to use our serializer to serialize it into complex data so over here what we can do is we can say serializer is equal to book serializer and then in here we're going to supply it with the book that we want to update so the instance that we want to update which is the book and then we need to supply it with the data that we that the user is passing in and that's going to be whatever it is that we want to change it to so over here we're going to say or we're going to say data is equal to request dot data now notice here when we created a post or when we created a book notice how we passed in data to the serializer we only passed and data is equal to request.data we didn't pass any instance because well we didn't have an instance we wanted to create an instance over here we're passing the instance and then we're passing the data that we want to update it to and so in the serializer when we only pass the data it's going to go to this create function right over here however when we pass the instance as well as the data then it's going to go into another function and this function is going to be called well you probably guessed it update so over here what we can do is we can create a function called update you can create self so it's going to take in self it's also going to take in the instance and it's also going to take in the data now in here we're going to run the update logic so we can actually grab this instance and then we can grab every single property in this instance and set it to whatever the data is so we can do something like data.title and then we can say that's equal to data dot get and then we can get to the title and then over here as a second parameter we can pass in the instance dot title so we're gonna actually have to do this for every single type this is really annoying i know but we'll figure out a way that we can actually ease this process a little bit later so over here what we're going to say is theta dot number of pages you can copy that paste that in here as well as paste that in here now let's see what else we need we need the publish date as well as the quantity let's copy that publish date publish date publish date let's also grab the quantity quantity quantity quantity let's get rid of this instance right here so this is all it is that we need to do and then what we can do is just save that instance we can do instance dot save and then we can actually return the instance itself so the new updated instance so now in the view what we can do is once we call this serializer it's going to hit that update function that we called so over here similar to what we did here we need to validate if the data is is valid because it might not be valid so if serializer dot is valid then what we want to do is we want to save that data so we're going to say serializer.save and we're going to return a response so we're going to say response we're going to say serializer dot data and now if we hit the else block and i'm not going to put an else statement for this i'm just going to say return and i'm going to say serializers.errors so serializer dot errors so let's give this a quick go see if this works the way that we expect it to let's go here and now i want to update this for example so let's say i want to i think harry potter's 2t so let's say i want to update the title so let's go here let's just grab this whole thing and i want to update the title so that it's harry potter like that so let's go ahead and execute this put request and you can see that it has changed if i refresh you can see it has been updated if i go to the list as well you can see that it has been updated all right so that was our wonderful put request the last thing that we need to do is our delete this isn't going to involve a serializer in any way because we don't have to transform our data we're just deleting a specific record so this one's definitely going to be the easiest so we're going to say if method if request.method equals delete all we really want to do is grab this book here we're going to say book dot delete that's it so we're going to say book.delete and then what do we want to return well we probably don't even want to return anything so i'm going to say return response and i'm just going to for now i'm just going to return an empty object that says delete and then here i'm gonna say true that's really all it is that i'm gonna do so let's go ahead and try to delete this now so let's go to slash book slash one uh slash book slash one what's going on here did i break the whole thing oh no i gotta go slash book slash one not list let's try to delete this by clicking here are you sure you wanna delete now you can see we get back delete true okay and now if you went back to our list you can see we only have this record here so that's pretty much all it is and that's really how endpoints work and how we can create apis in django the next thing i want to talk about is um statuses so right here we're really not returning anything and i honestly don't even want to return a thing so maybe i kind of want to do something like this where we don't return anything however i want to change the status from 200 to something like 204 which is no content and actually changing the statuses of different things is really easy all we have to do is go all the way up here and we need to import something from well rest framework we're going to import something called status so over here we're going to go to rest framework and we're going to say from rest framework we are going to import status so right here what we can do is actually supply it with a status code so what we can say is hey we want the status of this to be status dot and then over here i can say 204 no content another thing that i want to do is i want to be able to handle errors properly and what do i mean by that well right here what we're doing is and this should be a response actually apologies for that let's go over here response so i wanna when when we ever have an error when we ever have maybe a serialization error so for example let's say i want to update this so let's go to slash books slash two and i pass in you know something pretty invalid like banana fruit something yeah something invalid like this and i tried to update i tried to make this puts request uh what are we getting here we got a completely humongous error i wasn't expecting that error let's actually go to the post request so let's go over here let's try to add something in here and let's go ahead and add you know let's let's miss some property so we only have let's say the number of pages so number underscore of underscore pages um let's say that this is 555 but we forget all the other properties and we try to post you can see here that we're getting an error validation error however the http response is 200. so i want to somehow change this response to well 400. so let's go ahead and do that here best way to do that is as a second parameter say status is equal to status we can make this a 400 request so status dot and we can go all the way down over here to find some of the 400s we could just say bad request so now if we try to make this request and we get some sort of error let's go here and let's actually no sorry let's go here so if we try to make this request again let's go here supply with some invalid data so just let's apply the quantity supply with that and we try to post you can see now we're getting a 400 which is a bad request error all right this is really good so now another thing that we want to do is what if we cannot fetch a specific book so for example right now we only have one book inside of our database and it has an id of two whatever what it what if what if i did slash book slash let's say six well at this point we have this error this ugly error and i honestly do not like this error i want to kind of handle this on my own so what we can do here is we can actually place this here in a try accept block so we can say try so you can try to get the book now if there is any sort of error we can go ahead and return a response so we can return a response and we can say something like error and then over here we can say you know book does not exist like so and then we can also give it a status code so we can say here status is equal to status dot and we can say 404 for not found so now if we try to make this request again you can see we just get this wonderful error code book does not exist all right that's really all it is that we are needing to do there's nothing much other than that so that really concludes how we can actually make http requests with django this is really the knowledge that you need however now what we're gonna start doing is start simplifying our api to use some of the better practices and cleaner code in this section we're gonna do a little bit of refactoring so remember when i said a view is either going to be a class or a function well let's go ahead and actually refactor our views to be classes and the reason for this and you'll it'll be really apparent is syntactically it's going to be a lot cleaner to write all of this code with a class so what i'm going to do is i'm just going to go ahead and comment everything out we're going to we're going to work on this later but let's just comment things out and let's create a brand new class view so the first thing that we need to do in order to create a class view is we need to import a specific class view to inherit so i am going to inherit something called api view now this is one of many different class views that you can utilize and we'll look at some later on in the course but this is the one that we're going to start with so we're going to say here from rest framework we're going to import we're going to import and what are we going to import we're going to import api view and we're going to get that from so from classframework.views we're going to import api view all right so now that we have imported our class that we want to inherit we can go ahead and actually create the class itself so the first thing i want to do is let's go to the urls file right over here and we're going to need to create three separate classes for these things right over here so for each path let's begin with the list so over here what i'm going to do is i'm going to create a class and i'm going to call this book list book list like so and i'm going to inherit the api view now how are we going to perform the same thing now instead of actually using a decorator and saying that hey we want a get request here a post request here a delete request here instead we can actually really simplify the thing with a class float with the cat class view what we can do is we can actually utilize either a get post delete or put or patch method so if we want to perform a get request all we have to do is do get create a get function and then this is going to take in self as well as the request and then in here we can just have all of our logic so that same exact logic that we had right over here so let's just go ahead and uncomment this logic out i'm gonna go ahead and copy this and comment back it comment it back in we're gonna go ahead and indent this properly and what we need to do is we need to actually import book now we already have that up here somewhere so let's go ahead and import book as well as the serializer let's go here and let's import that in and there we go and we also need response so let's go ahead and import that in as well and now we're done so this should work so the only thing that we really need to do now is we need to go to our urls for now i'm going to comment this out and i'm going to comment this out and i'm going to import book list now so book list like so now this isn't enough this is a class what we need to do is tell it explicitly that hey we want this to act as a view so we just say book list dot as view really all we have to do all right so now what i'm going to do is let's go to our book list so let's go to slash book list and now it's yelling at us so it says here it takes one argument what was given to where is this uh in the app view oh yeah we have to of course invoke this and there we go so now you can see that it's working a okay now you can see this is allowing us to get data now i want to show you something let's go over here to the view and what i'm going to do is i'm going to define a post request now this post request is going to do nothing what i'm going to do is just very simply return response we're not going to do any logic in here we're going to do a return response we're going to return a dictionary we're going to say hello friend we're going to delete it later now by just adding this method we have just given this endpoint right here the ability to also perform post requests so here now what we can do is we can save that and refresh here and now you can see we have given our uh endpoint the ability to create post requests so this is significantly easier i like this a whole lot more all right let's just go ahead and create another class view so let's go over here and let's create a book create class we're going to allow it to inherit the api view and then what we're going to do is we're going to define a post function so we're gonna say self request and we're just gonna copy our code right over here uh where is that right here let's copy that in let's paste it here and let's go ahead and uncomment and tabulate there we go only thing that we're missing is the status so let's go ahead and also import that from here to here let's go ahead and do that and there we go so now we have our wonderful book create so inside of our urls we can uncomment this and we can go here book create i'm going to auto import it as you can see i'm going to say as view invoke that so now if we go to slash books we should be able to create another book let me just go grab the data here and then let's go to slash books slash where are you slash books let's create another book let's provide it with the name of uh what kind of book what what book let me think of a book here um gotta think of a book this is the hardest part of creating a course is thinking of book names i haven't read a book in a while actually uh let's just say um i don't know i'm just gonna make up a book let's just say gorilla gorilla let's say here 1000 and 222 is the quantity so it says here invalid expected a dictionary but got a list so what's going on here uh i'm not really actually sure let's see the the errors that we have so here we got the serializer seems like everything should be fine um okay so we have this path okay i don't think there's anything particularly wrong here we got the request request.data serializer yeah this looks good to me let's give this a go maybe i uh invalid data expected a dictionary but got a list hmm i wonder why that happened oh cause i probably returned that okay so let's see here let's just change this to maybe a real book name oh okay whatever let's go back to what we had before now if you post you can see that that is posted and it works okay okay let's go over here you can see we have both um things so now let's go ahead and create a uh another uh class view and this is just gonna be for you know just books in general i'm just gonna call it a book because this we can get we're going to also delete as well as put over here we're going to have our api view and then over here let's define a get so we're going to say get now this one's going to take in a self a request as well as the primary key the pk and now let's go over here let's go over here to the get and what we're going to do is we are going to grab this code this is the only code that we need for this now what we also need is to fetch the book itself and potentially throw an error if uh if the book is not found now instead of doing it in every single function what we can do here is we can actually grab this code which is right here this try catch block and we can put it in another function like this so we can say function we can say you can call this get book by pk which is primary key and then over here this can take in self as well as the primary key itself and then over here we can have this logic so let's uncomment that out let's go here da da should be good just like that and now over here what we can do is we can say book is equal to self dot get book by primary key so you can say get book by primary key and we can pass in that primary key so now what we can do is we can do the exact same thing but with an update so we can say put here and say self request and then pk we could also get that book by primary key because we're going to need it eventually let's go over here grab this code so the logic is the same but you can see it's a little bit simpler to actually execute this stuff and now what we can do is uncomment this out there we go maybe tabulated a little bit and there we go so that's update let's do a function for delete so function for delete request or self request pk let's grab the book and i think this one's really simple all we do is a book.delete on this one like so and respond with no content okay let's uncomment that and there we go completely done and right now we have the exact same functionality but you can see in my opinion this is significantly significantly cleaner i hope you guys kind of also see that i i really personally like the way that we've done things here we can just define the methods instead of having like a decorator and then having an if statement and checking if you know if this is equal to that that's just a lot of extra work that i i think we shouldn't probably handle as developers all right so that is pretty much all it is that i want to refactor in the view for now now let's actually move on to the serializers so in the serializers we have so what we did was we defined exactly how we want to serialize our data so once we want to turn it to json this is how we want to look if you get it back if you get it as json and we want to convert it to complex data we should get it looking something like this and it kind of led to a lot of goofiness like this right over here and honestly we have the um we have the uh we have this defined in kind of multiple places we have been defined in the model as well as the serializer itself and so this is just a lot of extra work which i think is unnecessary i think it would be great if the serializer can just read the types inside of the model itself and then just be able to interpret all this stuff for us and there's actually a way to do that relatively easily and right now in order to do that what we're going to need to do is inherit a brand new type of serializer and this is going to be known as let me let me comment this out actually just so we can have this for later i'm going to go ahead and probably push this to github so what we're going to do is we're going to create a brand new serializer or well the same serializer but we're going to call this but it's going to be of a different type it's going to be a book serializer let's go ahead and copy that actually and let's grab the imports because we're going to need both of these imports you're going to see how much simpler this is going to get so we're going to go over here we're going to say book serializer and instead of inheriting serializer.serializer what we're going to inherit is serializers dot modal serializer so modal or yeah model sorry i keep saying modal model serializer so you could probably imagine what this is going to do we're going to pass it the model and then it's going to be able to do a lot of these interpretations for us instead of us having to define things explicitly so what we can do inside of this serializer we can define another class called meta and then inside of this meta class we define the model and over here we can say that the model is equal to book and we can also define what fields we want to get back if you want to get back all of the fields all we say is field is equal to underscore underscore all underscore underscore so that's pretty much all we need to do that's it that's it instead of all of this junk over here i mean i'm apologies if i call it chunk but instead of doing all of this stuff and actually defining the create defining the update this is all we really have to do and this will actually inherently do all the update stuff as well as do all of the um create stuff as well as the get stuff so all these methods are going to be handled right over here we can get rid of this you don't need that so just to prove to you that this is going to work a okay let's just go ahead and well let's give it a test i'm going to refresh and over here it says type book has no attribute let's see here tag book has no attribute objects i wonder why that is so let's see here uh where is that in the code it's in the views file line 58 so let's go over here to the views file line 58 and right now okay so i did something incorrect here with the way that i uh the way i defined this class so over here we have book serializers we're importing this from here we're doing modal serializer okay i figured out exactly what was going wrong right here we call this class book and over here we also have the model being called book so there's just some naming conflicts so let's go ahead and fix that so instead let's just call this book detail something like that and also we're not even using it inside of our urls so let's go ahead and use that in there so we're gonna say book details let's comment that out and let's go here book detail as view so now with our refactored serializers as well as our refactored um yeah let's comment this back out let's comment this back in i was just doing some debugging there were a refactor serializer as well as our refactor views now what we can do is go ahead and refresh and everything should still work the same way that it has been working let's go ahead and try to create something let me go grab the data first okay so let's go here let's change this to la la land whatever let's try to create uh okay let's paste that in again let's go here so we're getting some json errors so over here we're gonna say lala just to make sure the json is good let's get rid of that comma that was probably it let's go ahead and post yes we can so now let's go to back to list just to see that we just created it now let's go to slash four to get this post number of pages null huh interesting why is that it's very strange okay so let's see what's going on here so over here get the primary key so we try to fetch the book itself and then what we're doing is we're serializing it i wonder why that's that's not working oh over here is the book oh we have to try to return the book so what we should do here we're not returning here so let's go here and return the book that we get back there we go so that should work okay so now let's go to four okay there we go okay nice little bug so now let's try to update let's pass in this stuff let's change it to tata land or whatever we can update awesome and we can also probably delete let's go ahead and delete and that works that should work let's go back to our list we don't have it anymore okay so you can see that it's just significantly simpler a lot simpler this is the the views are cleaner as well as the serializer significantly significantly cleaner now one thing i also want to note is um the serializer i kind of mentioned this already but it inherently validates things for us like it validates that you know we're providing it with the correct fields but we can also have our own validation in there so for example if we let's say don't want um any books that are titled i don't know maybe there's a book that we really don't want in our database let's just call it i can't really think of book names let's just call it diet coke that's what i have right next to me that's the book we absolutely do not want to have in our database we can actually have like this kind of specific validation for that so in order to do that what we can do here is right after the class we can create a function and we have to give that function the name of validate and then underscore the the thing that we want to validate what property we want to validate in this case it's title so this is going to take in self as well as the value of the title that we want to eventually validate so what we can say here is you know if if the you know if the value of title so the value of title is equal to diet coke which is obviously something we don't want for some reason we want to throw an error instead of actually returning that value back so what we can do here is we can just very simply do raise a validation error so we can go here and say raise and we can import from django forms so from django.forms we can import something called validationerror because this is just a validation error and we can just raise this validation error we can say no diet coke please all right and then if we don't hit the statement we can just return that value and this is really all we have to do for validation so if we went over here let's go ahead and let's try to add a book with data that is that has a title of diet coke should get an error let's go here let's go to slash books we don't care about the list let's go here so i'm gonna go ahead and try to throw this error so i'm gonna go here i'm going to say that the title is diet coke and let's go ahead and try to post this and you can see that that's not the error that i wanted we have a comma here so let's go here try this again diet coke let's go ahead and try to post that you can see here we're actually getting a validation error specifically on that title now one thing that we can also do is validations on the object as a whole uh we can actually do that by just very simply saying the function of validate so validates like that without any property name so over here we can do self and then over here we're going to get back the object itself you can call that data so here what we can say is you know maybe we don't want um maybe we don't want i don't know let's see here let's look at our properties again maybe if the book is you know if it's if it's larger than 400 pages and it's larger than 200 and 200 in quantity we don't want the book or something like that so we can do something like this we can say if and we can say if data and then of if the data what property we want number of pages number of pages is greater than so it's greater than let's say uh let's say 200 and and data of and the quantity so quantity here quantity is also greater than 200 then we want another we want to raise another error maybe saying that this is going to be too heavy for our inventory too heavy for inventory so that's the area that we're going to raise else we're just going to return the data itself so let's give this a quick go so in order to do this what we need to do is of course go here and uh let's go over here let's go grab this let's go over here to the books and what i'm gonna do is i am going to let's add another title let's call this python whatever and let's make this 300 and let's make this 400. and so now what we can do is we can make this post request and you can see here too heavy for i spelled inventory wrong oh i hope that's that's kind of clear i know these are kind of like goofy validations but i hope like it kind of gets the point across uh let's just fix that inventory we'll actually keep the validation just if you guys want to refer to them in the github repo all right and another thing that we can actually do um is we can actually create additional fields inside of the serializer this is what's really nice about this serializer what we can do here is if we want an additional field that is maybe dependent on additional properties over here we can say you know maybe description so this is another field that we want inside of our book and then here we can say serializer dot and then we can call this serializer method field and in order to actually define this description what we can do is we can create another function and it's going to be called get and then underscore whatever we called this over here so we're going to call it get description like that and then over here we're going to say self and then it's going to take in the data which is the object itself and over here maybe we can return you know something like this book is called and then we can do here plus data and maybe have a space here plus data dot uh where are we gonna call this or data uh we're gonna call this title and then over here we can say so it's called this book and then over here you can say and it is and let's do data dot number of pages long so let's go ahead and save that and now if we try to make a request to the list oh yeah we can't concatenate a string so can we do a two string here so you can do string we can wrap that in here make that number a string so let's go ahead and save that and now you can see that this book is called bad blood and it is 200 you can even call this pages long pages long okay so again hope you guys get the point you can do more creative things here that are more important
Info
Channel: Laith Academy
Views: 33,228
Rating: undefined out of 5
Keywords:
Id: mlr9BF4JomE
Channel Id: undefined
Length: 77min 57sec (4677 seconds)
Published: Tue Feb 01 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.