Chapter 2: Django Rest Framework
Intro to Django
link Django Rest Framework
By the end of this lesson, developers will be able to:
- Create serializers to format data attributes
- Create viewsets to create, read, update and destroy data
- Create an API router for handling endpoint urls
In this section, we take a deep dive into Django Rest Framework.
In a traditional data-driven website, a web application waits for HTTP requests from the web browser (or other client). When a request is received the application works out what is needed based on the URL and possibly information in POST data or GET data. Depending on what is required it may then read or write information from a database or perform other tasks required to satisfy the request. The application will then return a response to the web browser, often dynamically creating an HTML page for the browser to display by inserting the retrieved data into placeholders in an HTML template.
Django web applications typically group the code that handles each of these steps into separate files:
URLs: While it is possible to process requests from every single URL via a single function, it is much more maintainable to write a separate view function to handle each resource. A URL mapper is used to redirect HTTP requests to the appropriate view based on the request URL. The URL mapper can also match particular patterns of strings or digits that appear in an URL, and pass these to a view function as data.
View: A view is a request handler function, which receives HTTP requests and returns HTTP responses. Views access the data needed to satisfy requests via models, and delegate the formatting of the response to templates.
Models: Models are Python objects that define the structure of an application's data, and provide mechanisms to manage (add, modify, delete) and query records in the database.
Templates: A template is a text file defining the structure or layout of a file (such as an HTML page), with placeholders used to represent actual content. A view can dynamically create an HTML page using an HTML template, populating it with data from a model. A template can be used to define the structure of any type of file; it doesn't have to be HTML!
As a brief disclaimer, we are not going to work with Templates in this course. Instead, we will use a reactive web stack to host our pages content.
Without further ado, let's begin with the installation of Django Rest Framework.
pipenv install djangorestframework
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'catalog', 'rest_framework', ]
link Create API Router
To kick things off, we can create a new directory called
api, and file called
mkdir library/catalog/api touch library/catalog/api/urls.py
library/catalog/api/urls.py, add the default router from
from rest_framework.routers import DefaultRouter router = DefaultRouter() app_name = 'catalog-api' urlpatterns = router.urls
Here we initialized the root router. This acts as the "entry point" to our application. Up next, we will add two new endpoints:
Let's move on to our API views.
link Create Author, Book Serializers
Create a new file, called
library/catalog/api/serializers.py and insert the following:
from rest_framework import serializers from catalog.models import Author, Book class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = '__all__' class BookSerializer(serializers.ModelSerializer): author = AuthorSerializer(required=False) class Meta: model = Book fields = '__all__'
Let's break down this file, as it contains a lot of useful functionality.
- Whenever we query our
Bookserializers, we specify the attributes we want.
modelin order to fetch the correct database tables.
BookSerializerallow us to specify a list of fields as an array, or simply
When we use serializers, we are asking our database to transform a model into
link Create Author, Book Viewsets
Now that we created serializers, we can display
JSON data using a
Add a new file, called
library/catalog/api/views.py, and insert the following:
from rest_framework import viewsets from rest_framework.response import Response from catalog.models import Author, Book from catalog.api.serializers import AuthorSerializer, BookSerializer # 1. Define the viewset as a ModelViewSet class AuthorViewSet(viewsets.ModelViewSet): # 2. Specify the queryset as "all authors" queryset = Author.objects.all() # 3. Assign the serializer class serializer_class = AuthorSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
Let's break down this file, as it also contains a lot of useful functionality.
- First we define two viewsets, which subclass the
ModelViewSetprovided by Django Rest Framework.
- To query from each model in our database, we define a
queryset-- this is a list of data values.
- To fetch data from our
Bookserializers, we define a
serializer_class-- this is the class that transforms our models into
link Wire Up Default Router
It's time to return to the root router in
library/catalog/api/urls.py, and add the following:
from rest_framework.routers import DefaultRouter from catalog.api.views import AuthorViewSet, BookViewSet router = DefaultRouter() app_name = 'catalog-api' router.register(r'authors', AuthorViewSet) router.register(r'books', BookViewSet) urlpatterns = router.urls
link URL Updates
library/library/urls.py, insert the following:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('catalog.api.urls')) ]
Ready to test it out? Run the server locally, and visit
pipenv run python3 manage.py runserver
You should be able to read, write and edit your authors and books.
Congratulations, today we created a mini library API. WELL DONE!
In the next section, we introduce Django filters, permissions and pagination.