What is the Django REST framework (DRF)?
DRF is a toolkit built on top of the Django web framework. It comes with many helpful utility classes and objects that can help developers build robust APIs quickly.
DRF is a Django utility app that bridges your regular Django app, the Django framework, and the Object Relational Mapping or ORM Library, which communicates with the database.
Although Django’s built in templating system is great for developing web applications, DRF provides more functionalities. Because when it comes to API development, you need to be able to deal with other data types like JSON and XML and this is where DRF comes in handy.
You will frequently need to retrieve data from the database, process it, and then represent it to your clients as mainly JSON.
This conversion process is called serialization; One of the DRF’s biggest benefits.
With DRF, you don’t have to worry about transforming your database models into a RESTful API. It takes care of that for you with its support for data conversion utility classes.
Benefits of using DRF
Easy to integrate
It’s pretty straightforward to integrate DRF into your existing Django app. With just a few changes in the settings, you can have a fully functional Django app powered by DRF almost instantly.
Web browsable API
DRF comes with an API viewer that allows you to send different HTTP methods with data and evaluate the output without needing an external application like Insomnia.
This API viewer has limited features, but it works when you want to quickly experiment with your APIs.
Request and response processing
DRF comes with its own request and response objects, which are wrappers of the regular Django HTTP response and HTTP request object, but offers more flexibility on processing data in and out.
Readable HTTP Status codes
The status module has a list of human-readable HTTP Status codes. When you use the status module from DRF, you don’t need to send status codes like 404 or 200 with your responses.
Instead, you can use a readable representation like status, Status.HTTP_ 200_OK
or Status.HTTP_404_NOT_FOUND
.
CRUD helpers
The Django Rest Framework’s built-in view set classes, make it quick and easy to create a functional CRUD. You can extend the workflow if you need to. But for basic data manipulation, the view set from the Django Rest Framework works really well.
You will have the full support for all the necessary HTTP methods out of the box.
Serializers
The DRF package comes with a number of built-in serializers to help with data conversion between models.
Serializers also support converting other non-ORM objects. This can be a great time-saver. A serializers make it easy to convert complex data into native Python datatypes that can be quickly rendered into JSON, XML, or other content types.
Serializers and DRF also provide a method called deserialization, which converts requested data and connects them back to the existing models.
TIP
This deserialization process also validates the user input to ensure no data corruption.
Authentication
DRF also comes with great support for modern API authentication systems. Building an authentication layer is a complex process and usually takes time. But with DRF and some supporting packages, you can effortlessly develop an authentication system for your Django app.
You can also enable social connection where your users can authenticate and authorize themselves using an external provider like Facebook and then consume the APIs.
Installing and setting up DRF
pip or pipenv
Now the question is, are you going to use pip or pipenv. If you’re eating just pip, you’ll need to manage all those dependencies and keep track of those packages. You will also need to set up the virtual environment and configure it to function correctly. However, is in pipenv, which works on top of pip, makes everything easier with a lot of work going on behind the scenes.
pipenv creates and manages the virtual environment. You don’t have to manually configure so many things to make it work.
Configuring the DRF
In the settings.py
and in the INSTALLED_APPS
list, add rest_framework
.
Also include the BookList
app.
The DRF comes with a more advanced version of the HTTP response, which is Response
.
You have to add the api_view()
decorator to the methods; This so you can use the Reponse
class
Can i accept any HTTP methods?
Note that DRF is not accepting an HTTP post call to this end point and it’s returning a message saying method post not allowed. This is happening because you did not instruct DRF to accept any other HTTP methods than GET, which is the default one.
If your API endpoints need to accept other HTTP methods like POST, PUT, or DELETE you need to define them in the API view decorator.
Better API view with decorators
Benefits of decorator in DRF
The views from the [[#[Installing and setting up DRF](https //www.coursera.org/learn/apis/lecture/EE4hl/installing-and-setting-up-drf)|Previous note]]:
The @api_view()
allows you to use the Response
.
Nice Browsable interface
One of the most significant benefits of using the API view decorator is that it turns your standard AP output into a nice brow sable API interface. But you must use the response class to get this view.
If you change the view function to →
you see →
What HTTP method your function should support
OPTIONS button
By clicking on the Options button, you can view helpful information about the current API endpoint, such as which rendered DRF users to dispel the API put, what types of data this API accepts, and so on.
Throttling or Rate-limiting
The API view decorator also allows you to implement Throttling or Rate-limiting, by which you can define how many times someone can access this API in a given period.
Authentication
The API view decorator also helps you to authentic your endpoints so that only authenticated users can call this API endpoints.
Different types of routing in DRF
Introduction
The Django REST framework provides different ways of URL mapping or routing in an API project. Besides the traditional style of routing, there are other routing techniques that can save you time while developing. In this reading, you are going to learn about both traditional and other techniques.
Note: All the routings should be done in the urls.py file in your Django app.
Regular routes
The code below maps a function from a views.py file to an API endpoint. Don’t forget that you have to import the path function from the django.urls module first.
This URL pattern maps the books function to the /api/books
endpoint. You already know how to specify which HTTP methods a function view can serve by supplying them in the api_decorator
function. The following code allows any function view to serve both HTTP GET
and POST
methods.
Routing to a class method
If you map a specific method from a class, then you need to declare that method as a @staticmethod
first. After that, you can map it in the urls.py file. Here’s an example of a class in the views.py file.
You can also map this listOrders
method in the urls.py file as follows.
Routing class-based views
You can save a lot of time in DRF by mapping a class that extends the APIview
. You don’t need to individually map every method of such classes. In an upcoming video, Function and class-based views, you will learn that such classes have HTTP verb-specific methods inside them. When a class extends APIview
or generic views, you can simply map those classes in the urls.py file.
Here’s the code of the class that extends the APIView
.
And here is how you map this class in the urls.py file. All you have to do is map the class as a view against an endpoint.
Now you can make HTTP, GET
and PUT
calls to the /api/books/{bookId}
endpoint without issues. If the class has post()
, delete()
and patch()
methods, it will work with HTTP POST
, DELETE
and PATCH
methods too.
Routing classes that extend viewsets
You can have classes that extend the different types of ViewSets
in your API project. Just like the classes that extend APIView
, these classes also have specific methods used to respond to different types of HTTP requests. Here’s an example of a typical class that extends the viewset.Viewset
class.
You can map this class in the urls.py file in your Django app as follows.
Notice how the HTTP verbs are mapped with each method in this class. Also, note that both the list()
and retrieve()
methods are present. The list()
method is used to display all books, and the retrieve()
method is used to display a single book.
After this mapping, you can access the http://127.0.0.1:8000/api/books
endpoint with GET
and POST
methods. While you can access the http://127.0.0.1:8000/api/books/1
endpoint with GET
, PUT
, PATCH
and DELETE
.
Routing with SimpleRouter class in DRF
If you have a class that extends ViewSets
then you can use different types of built-in routers to map those classes in your urls.py file. Doing things this way means you don’t have to map the individual methods as you did in the previous section. Initiate a SimpleRouter
object and map the class in the urls.py file in your Django app as follows.
After mapping, you can access the api/books
and api/books/1
endpoints with the same methods as in the previous example.
Did you notice that the argument trailing_slash=False
was passed, instantiating the SimpleRouter
object? Without this argument, your API endpoints will have a trailing slash. And, since you don’t want a trailing slash at the end of your API endpoints, you have to pass this argument.
Routing with DefaultRouter class in DRF
There is another type of router called DefaultRouter
which provides an extra benefit over the SimpleRouter
. It creates an API root endpoint with a trailing slash that displays all your API endpoints in one place. You can use it this way in the urls.py file.
Again, after mapping, you can access the api/books
and api/books/1
endpoints with the same methods as in the previous examples.
Additionally, you can access the API root view when you visit the http://127.0.0.1:8000/api/
endpoint. This will display all the available endpoints as in the screenshot below.
You can read about all of these routers and more in the DRF documentation shared in the additional resources of this lesson.
Conclusion
In this reading, you learned about different types of URL routing for your Django REST framework-based API project.
Generic views and ViewSets in DRF
Introduction
DRF comes with many generic views and ViewSet
to speed up API development. When you use these classes, you don’t need to start from scratch and using them will reduce the code in your API project. In this reading, you will learn about different types of generic views and ViewSet as
well as their purposes and benefits.
ViewSets
ViewSets
are simple class-based views, but they come with benefits. There are a few ViewSets
classes available in DRF that you can use to quickly scaffold a functioning API CRUD project. You can also provide permission classes and throttle classes to allow authenticated API calls and rate limiting.
To use these classes, you must import the viewsets
module from the rest_framework
:
ViewSet
There are a few ViewSet
classes but the foundation is ViewSet
and it extends the APIView
. When your class-based views extend a ViewSet
you get browsable API views out of the box. Except for that, every ViewSet comes with a method naming convention for easier one-line routing that saves a lot of time.
When a ViewSet
is used to deal with a collection of resources, you can write your business logic in list()
and create()
methods inside this class.
Class method | Supported HTTP method | Purpose |
---|---|---|
list() | GET | Display resource collection |
create() | POST | Create new resource |
You can use the following methods to write the business logic when a ViewSet deals with a single resource.
Class method | Supported HTTP method | Purpose |
---|---|---|
retrieve() | GET | Display a single resource |
update() | PUT | Completely replace a single resource with new data |
partial_update() | PATCH | Partially update a single resource |
destroy | DELETE | Delete a single resource |
When you extend a ViewSet
, you will have to manually write code to perform the database operations. But there are two more ViewSet
classes that can automatically do that for you. This is how you extend a ViewSet
class.
ModelViewSet
If the class-based view extends a ModelViewSet
, it can automatically handle CRUD operations for you. All you must do is give this class a queryset
and a serializer, and everything else will be done automatically. You don’t need to write code for all those database operations anymore. Later in this course, you will see a practical example of using ModelViewSet
to write a functioning CRUD API project with only a few lines of code. Here’s an example of how to extend this ViewSet
.
ReadOnlyModelViewSet
As the name suggests, when your class-based views extend a ReadOnlyModelViewSet
, it can only display a single resource and resource collection. No write-operation is allowed by such views, so it doesn’t handle POST
, PUT
, PATCH
or DELETE
methods. Here’s an example of extending a ReadOnlyModelViewSet
.
Generic views
Generic views are another way of quickly writing class-based views to scaffold fully functional CRUD API projects. There are several generic views that offer a particular functionality, like displaying resources or creating a new resource and so on. All you must do is extend these generic views to make your API endpoints work.
To use these generic view classes, you must import the generics module from the rest_framework
.
All generic view classes require a queryset
and a serializer to work properly.
Here is a list of generic views in DRF and their purposes.
Generic view class | Supported method | Purpose |
---|---|---|
CreateAPIView | POST | Create a new resource |
ListAPIView | GET | Display resource collection |
RetrieveAPIView | GET | Display a single resource |
DestroyAPIView | DELETE | Delete a single resource |
UpdateAPIView | PUT and PATCH | Replace or partially update a single resource |
ListCreateAPIView | GET , POST | Display resource collection and create a new resource |
RetrieveUpdateAPIView | GET , PUT , PATCH | Display a single resource and replace or partially update it |
RetrieveDestroyAPIView | GET , DELETE | Display a single resource and delete it |
RetrieveUpdateDestroyAPIView | GET , PUT , PATCH , DELETE | Display, replace or update and delete a single resource |
Example code
If you want API endpoints to be capable of displaying resource collection and creating a new resource, you have to extend both ListAPIView
and CreateAPIView
, or just ListCreateAPIView
. Both of the following lines of code do the same job.
And
Just like ModelViewSet
, you must give these generic view classes a queryset
and a serializer and you don’t need to manually write code to perform these database operations.
Authentication and selective authentication
If you want all API calls to be authenticated in a class-based view that extends the generic views, you can add the permission_classes
public attribute in the class.
If you want to selectively enable authentication for some calls, like POST
, PUT
, PATCH
and DELETE
then you need to override the get_permission
method in your class-based view like this.
This way, anyone will be able to make GET
call, but other HTTP methods like POST
, PUT
, PATCH
and DELETE
will require authentication or a valid user token.
Return items for the authenticated user only
Sometimes in a class-based view that extends a generic view, you may want to return resources created by the authenticated users only. In that case, you need to override the get_queryset
method. The following code in a class-based view returns only those orders created by the authenticated user.
Override default behavior
Though generic views automate everything, you still have full scope to change the default behavior by overriding any of the default methods. Here is an example that returns a simple static response instead of the resources.
The other methods you can override are post()
, put()
, patch()
and delete()
.
Conclusion
In this reading, you explored the ViewSet
classes and generic view classes which can help you to scaffold a fully functional CRUD API project in a very short time.
Function and class-based views
Function-based VS Class-based views
Function-based views advantages
- Function-based views are easy to implement
- offer better readability
- it’s easier to use decorators with them
- you can quickly write a one-off solution using function-based views
Class-based views advantages
- With class-based views, you don’t need to write as much code
- there’s less code duplication
- you can extend the clusters and add features that anytime
- you can write specific methods for each type of HTTP request
The views.py
from before
Open the views.py file from the same booklet project you worked on before, you’ll create your first class-based views in this file. Class-based views help you to keep your code clean and less cluttered, and you can avoid writing extra code by reusing the common functionalities.
To create a class-based view in a DRF project, you must extend the APIView
class, so let’s import it first from the rest framework module.
You also need to import the Response
class.
NOTE
When adding methods in a class name, you should name them the same as the HTTP verbs. For example, get and post.
This endpoint will not accept an HTTP post request because there isn’t a post method in this BookList
class. Let’s add one. The post method also accepts three or four arguments, like the get
method.
Remember, you’re using the browsable API view. This means you can taste this post method right from your browser.
Filtering the contents
What if the APA client wants to list the books by a specific author, how can we exit the query string parameter from the falling request?
You can accept the JSON or form URL-encoded data elements in a post method using request.data.get('')
.
Now, visit the book’s endpoint in the browser, scroll to the bottom, and in the Content textbox, add this JSON data.
This is called a payload. Payload is a common term used for any JSON data or form URL-encoded data that you sent to an API.
Click on the post button and check the result.
Accepting primary key
Click the Put button, and note the output.
Like the APA view decorator, you can use throttling and authentication policies.
Django debug toolbar
Add the debug_toolbar
in the INSTALLED_APPS
in the settings.py
.
Add a special URL pattern in your project.
Include the debug_toolbar.middleware.DebugToolbarMiddleware
in the MIDDLEWARE
section in settings.py
.
Finally add the following at the end of the settings.py
file:
This section is not in the settings.py
file by default, so you have to add it.
Now if you go to any API endpoint, you will notice the debug toolbar at the right side of the screen.
The toolbar sections
Settings
The settings section displays all the settings you have in your settings.py file and other settings used throughout the project and the installed apps.
If you want to override a setting, copy its name and value from here and then add it in the settings.py file with the new value.
Headers
This section includes all the header information sent to this request and those generated in the response.
SQL
The SQL section is one of the most useful sections in the Django debug toolbar. It shows the list of the SQL queries executed for this end point. This is a place where you often check for performance tuning and optimization. From here, you can easily detect if more than required SQL queries are running and then take the necessary steps to fix them.
Static files
The static file section displays all the static files loaded for the current request and those used by the installed apps.
Developers usually do not serve static files from API requests. Still, you should know about this.
Cache
The Cache section displays applications that use the Cache. By now, you should know that Cache helps to reduce the several load for a great extent.
Profiling
This is unchecked by default and you can enable it using the checkbox next to it. The profiling section displays the complete call stack. When you make a request, a file in your project intercepts the call. Then it invokes another function, that function calls another one and it goes on and on like this. It then comes to your function or class based views and thereafter, jumps to another file to generate the response and display it.
So, the profiling section contains this full code execution flow.
NOTE
Please note that the Django debug toolbar will only be visible during development time when you use the browser API. It will not show when you’re making the API call in the production view or when it returns data as the client apps are consuming the APIs.
Restaurant menu API project with DRF
Create a LittleLemonAPI
app, and add it to the settings.py
. Ensure to add rest_framework
too.
Another thing you need for this project, is a serializers object. By now, you know that serializers helped to convert model instances into Python datatypes that can be displayed as JSON or XML. It also helps you to convert HTTP request body into Python datatypes and made them to a model instance.
Create a serializers.py
in the app:
Make sure it has every field in the models section.
ListCreateView can display records and accept Post calls to create new records. To function correctly, at least CreateView needs two items, a queryset that retrieves all the records using a model, and a serializer class to display and store the records properly.
At this point, you don’t have any menu items, so none are included in the output. It’s time to create records.
Since you have extended listcreateapiview, this menu items endpoint automatically supports HTTP post calls. Scroll down and you’ll notice a form to add menu items with the title, price and inventory fills.
For single item: http://127.0.0.1/api/menu-items/{itemId}
, you need to create another class in views.py
.
If you scroll down, you can see a form that you can use to update this record. There is also a Delete button, to delete the record.
You can send HTTP, get, put, patch, and delete calls to this endpoint, which works without any issues.
Additional resources
The following resources will be helpful as additional references in dealing with different concepts related to the topics you have covered in this section.
Django rest framework toolkit for building web APIs
Django debug toolbar documentation
Django Debug toolbar source code
DjangoPythonHTTPAPIRESTRESTfulDRF
Previous one → 3.Writing your first API | Next one → 5.Django REST framework essentials