in this video we're going to look at serializers in Jango R framework and this is one of the most important things you need to know about the package in the first video we did the setup of the models that we have in this jangle application so if you look at models.py we created these models in the first video in this series we're now going to move on and look at jangle rest framework and what we're going to look at in this video is the serializers so we're going to come to that in a second but I want to go to the installation section for rest framework and what we're going to do to start with is basically add rest framework to our application so you need to install it of course using pip or another tool like UV and that should already be done in our project because if you look at the requirements. text file that was specified in the starter code so when you install those requirements into a python virtual environment it's going to install Jango rest framework so now that we know it's installed we can go to settings.py and if we look at the installed app setting we're going to add that right at the bottom here so we're going to add rest framework to installed apps just as it says here in the documentation so now that we have rest framework and installed apps what we're going to do is go back to our application and within the API directory that's the Jango application I'm going to create a new file here and we're going to call this serializers.py this is a file where we're going to store all of the serializers for this project but before we start writing those I want to go to the API guide and I want to go to the documentation for serializers now let's see what these are according to the Jango rest framework docs serializers allow complex data such as query sets and model instances to be converted to Native python data types that can then be easily rendered into Json XML or other content types and serializers also provide deserialization so that allows the P data to be converted back into the complex types such as the jangle models and the jangle query sets and that happens after first validating the incoming data so basically with serializers you can convert your jangle models to Json data and that can include query sets of model mods you can convert that all to a list of Json data and you can also take incoming Json data and deserialize that into the complex data types such as Jango models and query sets now serializers and rest framework they work similarly to D jango's form and model form classes so what Jango res framework provides is a serializer class that gives you a powerful generic way to control the output of your responses but it also provides a model serializer class which is a useful shortcut for creating serializers that deal with models model instances and query sets so let's move on to the section here so what we have is an example of how to actually declare a serializer so here we have one called comment serializer and you can see that it inherits from the rest framework serializer class and what you can add to your serializer are the fields that determine what is in the output of the response for example an email field and just like jangle models and forms we have these fields that you can add to your serial izer for example a serializers email field car field and also a date time field here so basically imagine you want to get a list of comments the serializer that we have here is going to determine what fields are present in the response based on the fields that we actually add to the serializer class that's what's going to be converted from the python data types into Json data and vice versa if you're deserializing some incoming data now what I want to do just now is go back to our application and go to models.py we have a product model now imagine we wanted to convert that model or a query set of products into Json data that's what we're going to do in a second and return some Json data to the client but in order to do that we need a product serializer so let's go to serializers.py and at the top from restore framework we're going to import the serializers module so import serializers and because we're going to Define serializers for all of our models I'm going to import the three models that we are interested in here the product the order and the order item now we can create a serializer class after we've imported those so let's create one called Product serializer now we're going to inherit from the serializers do model serializer class so we're going to inherit an extend that class and that allows you to create an inner meta class just like you do with jangle model forms so when you have a model serializer you tie it to a model using the model property of the meta class and because this is a product serializer we're going to tie it to the product model and then we specify the fields that we actually want to serialize to Json for example if we're sending a response containing a list of products now we're going to pass a tuple here with all of the fields that we want to convert to Jason so we want the product's name to be converted to Jason so I'm going to add that as the first field here to this tiple and let's add one field per line here so name and I also want to add description and what have we got price as well so we want the product's price to be present in the Json response and also if we go back to models. Pi we want to see whether or not the product has items in stock so we're going to add the stock numbers as part of that response now I'm not going to add the image field because they're all null at the moment so we have four out of five of the fields present in the fields attribute of the meta class here on the product serializer so what's going to happen here is that the model serializer is going to look at the model and it's going to look at the types of each of these fields that we've added so for example the name is a car field and the description is a text field the price is a decimal field and so on and the serializer is smart enough to know which serializer field to use for each of these fields on the model I'm going to go back to the documentation for now and we're going to look at a page on serializer fields and this will be linked in the description of the video the fields handle conversion between the Primitive values and internal data types and they also deal with validating input values as well as retrieving and setting values from parent objects so there are some arguments we're going to look at later in the series you can add Arguments for example to make a field read only and if a serializer field is read only they're going to be included in the API output for example in response to a get request but they're not going to be included in the input during create and update operations and we also have a right only field as well that does the opposite so it's just getting used to this notion that a serializer class in jangle R framework it does two things essentially it converts the complex models and query sets that you have in jangle to Json data but it also can be responsible for incoming data converting that Json data that might be sent in the body of a post request to the complex objects and that's the deserialization process and what actually happens with the serializer depends on the endpoints that you have in your application and it depends on the view classes that you're going to use and we're going to see a lot of examples of that later on now at this stage I want to show how to write a field level validation function on our serializer so let's go back to the product serializer and let's imagine that we want to allow clients to create a new product in the database using a post request and we're going to see examples of that later in the series now the price field here we don't want that to be less than or equal to zero otherwise it doesn't have a price and that doesn't make sense in the context of a product so what we can do is we can actually write a validation function on the serializer and that's going to make sure that when the data is sent the serial realizer is going to attempt to convert that but any validation that fails is going to prevent that conversion occurring and you can then send the appropriate response back to your client so let's write a function here and I'm going to write a function called validate price and that's going to take self and a value as the arguments now let's explain this a little bit by going back to the documentation and I'm going to go to the API guide and look at the page on serializers at the left hand side you can see we have a section on validation so I'm going to go to that just now and we're going to cover the valid function very soon but if we go down here to field level validation on a serializer as you can see you can specify custom field level validation by adding a validate uncore field name method to the serializer class and these are similar to the cleancore field name methods that you find on jangle form classes so if you're familiar with those it's the same concept but it uses the validate uncore field name for the name of the function and these methods they take a single argument and that's the value that requires valid so you can see that in the documentation for this validate title method and the title is a field on the serializer subass and that's a carfield and if we look at the validation function here it's taking that value and it's lower casing it here in the value. low statement and it's checking if that statement or if that value rather does not contain the word jangle and if jangle is not in that then it's going to return a validation error that the blog post is not about jangle so that's how you can write these validation functions on the field level on a serializer class so let's go back here and we're going to write our validate price function all we need to do here is check if the value is less than or equal to zero and if that's the case what we can do is we can raise a serializer do validation error and I'm going to pass a string in here that the price must be greater than zero otherwise if there's no error in the value in other words if it's greater than zero we can just return that value and that's then going to be passed on to the next stage and if all of your validation functions pass successfully and all of the field level validation works then eventually jangle rest Frameworks serializer is going to convert that incoming data to the more complex objects and then you can create models and query sets from that data now what I want to do now is we're going to write a jangle view function that's actually going to use this product serializer so let's go back to views.py within this application we currently don't have any views from the starter code but we're going to write a function based view for now but later on we're going to see the power of J R Frameworks class-based views for example generic views and view sets but let's start simple here we're going to look at function based views and we're going to look at how to actually work directly with the serializer classes now I'm going to remove the import at the top and I'm going to bring in three Imports here first of all we're going to import the Json response from jangle and we're going to import the product serializer that we just created as well as the product model class then we're going to create a view function here called product list so let's imagine that we have these product products in the database and we want to return a Json response with all of the products converted from those database objects into Json data so a jangle view will take the request as the first parameter and then we're going to fetch all of the products from the database and we can do do that with an orm query and that's product doobs doall once we have all of the products what we can do is create the serializer so I'm going to create a serializer variable here and we can instantiate the product serializer once we instantiate that we can pass to it a list of the objects that we want to actually convert from objects tojson data so what I'm going to pass in here is the query set of all of the products and because that's more than a single object we can pass or we have to pass many equals true as a keyword argument so if you're serializing a single jangle model instead of a list of products then you don't need to pass many equals true but if you have more than one model in other words if you have a query set you need to pass many equals true here in order to convert that to Json data now the final thing to do here in this jangle view is actually to return an HTTP response we're going to return a Json response here and what we can pass in here is a dictionary of data and that's going to be represented in the Json data so I'm going to create a key called data and what we can do to access the serialized data representing these products is we can take the serializer and get the dot data attribute and this attribute has the serialized representation of the products so we can add that there and we can then return the Json response so now that we have the jangle view function we can go to urls.py and what we're going to do here is add a path and because we're getting a list of products from the database the rest API convention is to have a URL / products to represent that resource that we're getting back in the API so/ products when we send a get request to that URL we want to get back a list of all of the products in the database and the view that we're going to call here is the product list view that we just created and we can now save urls.py so now that we have this what I'm going to do is bring up the terminal and inside the python virtual environment we can run the Django development server and once that's running we can go to the browser and we're going to send a request to localhost 8000 SL products so let's go to the browser just now and when we send that request to this endpoint you can see we get back a key here called Data in the response and the Json response and that maps to a list of products and each product has the keys that we specified in the jangle rest framework serializer so we can see the name description the price and the value of the number in stock and if we wanted to change this for example to remove the description that we have here we can simply go into serializers.py we can Target the fields on this model serializer and we can just remove the description field here and save this and then if we go back to the browser and refresh the page it's going to send a new request and the response this time based on the the serializer fields is not going to contain that description so it's very easy to create a serializer and tie it to a model using this model serializer class and then determine which Fields should be present in the responses and you can also determine if it's an incoming request to create new data or update data which Fields you actually want to be present in that incoming response so that is very flexible and Jango res framework makes it very easy to create these serializer classes and we're going to see later on that we don't even need to do this kind of work here because some of the views that are provided by res framework are going to handle all of this code here for the serializers automatically now even though that works automatically I did want to include a section on the serializers and how you can pass query sets and models into the serializer and get the serialized data here I think it's important to know a little bit about how it works behind the scenes and that's what we're doing here we're taking the product serializer we're passing in a query set and because it's a query set we pass in many equals true and then we're returning directly adjacent response in jangle with the data that's been serialized as part of that response now one thing to note here is that jangle R framework actually comes with a request and response object and these objects augment the existing jangle request and response objects so let's go back to the rest framework documentation and I'm going to go to the API guide and we're going to look at the responses here so as it says here rest framework supports HTTP content negotiation by Prov providing a response class that allows you to return content that can be rendered into multiple content types depending on the client request and the rest framework response class is subclassing this simple template response from Jango Now using the response class it provides a nicer interface for these content negotiated web API responses now what does that actually mean let's get down to the section on creating responses so unlike the regular HTTP response in jangle you don't instantiate response objects with rendered cont content instead you pass in unrendered data which may consist of python Primitives now if you look at the signature for the response it takes data as an argument so what we're going to do here is just go back to our view that we've got here and at the top I want to import the response object from Jango rest framework so from rest framework. response we're going to import that response object and I also want to import a decorator here called API view now before we add these to the code again I'm going to go back to the documentation and I'm going to go to a section on function-based views so if we go to the API guide here and go to the page on views there is a section here on function based views and we're going to see how to apply a function based view in jangle rest framework now later on in the series we're going to use exclusively class based views because they are very flexible and there's also better support for things like throttling and caching and filtering and so on but what we're going to do just now is we're going to look at the functional approach now what we can do is decorate our function with with the API view decorator so let's do that just now and I'm going to decorate product list with API View and we can actually pass some methods into that as you can see here so I'm going to pass a list of HTTP methods that are valid for this particular View and we only want to allow a get request in order to return a list of data so HTTP get requests are going to get back data from your backend from the server so we're going to limit to get requests here using API view decorator and passing get and as an argument now once we've got that we can change the Json response and what we're going to do instead is we're going to return a jangle rest framework response object and that's going to perform that automatic content negotiation that was mentioned in the documentation and we're going to pass serializer do dat into that and remember if we look at the response object it's going to expect that data that we're going to send back as part of the response so we're sending back the data that's been serialized here so let's now save this and go back to our API here and when we refresh this you can see we get back a different type of response it looks a lot better in this View and this is called the jangle rest framework browsable API so one of the benefits of using some of these Primitives from rest framework instead of just the Json response is that we can access the browsable API as you can see here and that provides options for example to convert to different HTTP methods and we only have a get request for this endpoint but if the endpoint accepted a post request you could also see a form on the page that would allow you to send data to the endpoint so the browser Bol API it provides humanfriendly HTML output for each resource when the HTML format is requested what I'm going to do is load another page in the Jango R framework documentation so I'm going to go to a section on the browsable API and that's under the topics header at the top and if we go down to the format section here by default the API is going to return the format that's specified by the headers which in the case of the browser is HTML but what we can do is we can add a format keyword argument to the URL in the request and you can look at the raw Json response in the browser by adding format equals Json as a keyword argument so let's go back to the URL at the top here and what we're going to do is add that format equals Json argument and we get back the initial representation of the data so we can change the type of data that's requested here just by adding that format parameter to the URL now this output is controlled by something called renderers in jangle rest framework so if we go back one more time to the documentation I'm going to go to the API guide here and there's a section on renderer so rest framework includes a number of built-in renderer classes and these allow you to return responses with various media types now the one that we're using for HTML is this browsable API renderer and that's going to render the data into HTML for the browsable API as you can see here on this page and when we add the format and set that to Jason in the URL we are getting back a different response and that's BAS based on the Json renderer now typically in a web API you're going to return Json data and you may also return the HTML format if you're doing some development and debugging but there's actually quite a lot of these renderers available as you can see in the left hand side we have some for HTML forms and also multi-art renderer and if we click that this is used for HTML multiart form data and that's useful if you're uploading files to your API this is one of the renderers that can be used for that now if we go down to the the bottom here we have some thirdparty packages for rendering in different formats for example yaml XML Json p and we also even have renderers for pandas and for latch now in this course we're going to stick to the basic renderers and that's Json and the browsable API renderer but this is just to touch upon the fact that these exist in jangle rest framework but it's not something that we're going to have to worry about too much in this series now I want to finish this video with an example of how to serialize a single item based on a parameter in the URL so you can see at the moment we have a get request to/ products and that's going to return all of the products converted to adjacent and the response data so that's working with a query set of objects if we go back to views.py the query set that we're pulling out here on line 10 and that's product. objects. all now imagine we wanted to get a response for a single product based on its primary key so if we go back to the response here the first product here is the book A Scanner Darkly and that has an ID associated with it now we can view that ID by going back to serializers.py and we're going to add the ID as part of the data that we want to convert to Jason so let's add the ID which remember is an implicit field on the jangle model so unless you exclusively add a primary key to the model it's going to add the ID by default when we refresh this you can see we get back the ID for each of those products so what I want to do is go to the URL and go to SL products SL1 and I want to get back the response for that particular product and not the quy set containing all of the products but at the moment we don't have a URL for this so that's returning page not found and 404 so what we're going to do is add a URL for this so let's go back to urls.py and I'm going to add another path below the one that we have and that's going to contain a path parameter for the primary key of the product now instead of a list view this is going to load up a view called Product detail that we're going to create just now so let's save this and go back to views.py and what I'm going to do is just copy this view that we have just now and I'm going to paste that below here and we're going to change the name of the view to product detail now because we're adding a path parameter here called PK what we need to do in order to accept that in the jangle view function is add the PK parameter here and then we can use that primary key from the URL within the logic of this function so instead of looking up an object here or rather instead of looking up all objects I'm going to remove this line of code and we're going to get back a single object by calling get object or 404 which is a function from jango's shortcuts module so let's go to the top here and I'm going to remove this Json response from jangle do shortcuts let's import get object or 404 and then let's go back down to our function so we're getting a product here and we need to do the lookup so it's going to be on the product model and we want to look up by the primary key so get object or 404 the signature of this function is to take the model that you want to look up and then the lookup parameter come after that so in this case it's just the primary key and we want to get back a product from the database based on that primary key now once we have a product that's going to be a jangle model it's not going to be a query set of models so we're going to pass that product into the product serializer to convert it from a jangle model to Json data and because it's a single object we don't need many equals true so once we've changed this up and we now have this view function that fetches a single instance from the database a single row and then serialize that by passing it into a product serializer we can now save this and go back to the browser and this page where we got a 404 before we're going to refresh this and this time you can see we have the data coming back the Json data for that product and if we change the url from one to SL2 we get back the data for the second product which is this coffee machine so that's going to be all for this video we've created two function based views and we've added Jango R framework serializers to convert our product data to Json and we saw a custom way that we can use these serializers by passing the model or the query set into the serializer and then getting the data and returning that as a rest framework response and we've decorated these functions with the rest framework API view what I want to do in the next video is I want to look at nested serializers and that's going to look at the relations that we have between some of these models for example if we look at the order model that has a foreign key to the user model we want to represent that in a nest relationship so that when we look at the Json data we can see which user is attached to an order we're going to look at nested serializers in the next video but thank you for watching this video if you've enjoyed it give it a thumbs up and subscribe to the channel for more and if you want to support the channel check out our coffee page in the description thanks again for watching and we'll see you in the next video