Django Rest Framework
Once we have the data in our backend, we want to expose it to be consumed by our React frontend. Django, per se, is a traditional Web framework, it produces the html files, not json documents. There is this amazing library, called Django Rest Framework (DRF), which allows to easily add the ability to add the Rest API to the Django application. At the moment, DRF is not technically a part of Django and must be installed separately
pip install djangorestframework
Once installed, we need to enable it in the
INSTALLED_APPS = [ #.... "rest_framework", ]
In order to map models to the json documents, DRF utilizes the concept of
serializers. Let’s create one, In a new file
from rest_framework import serializers from pixies.photos.models import Photo class PhotoSerializer(serializers.ModelSerializer): class Meta: fields = ["id", "url", "caption", "details"] model = Photo
We are saying essentially, for every Photo entity we want the json document to include
details. Notice that we excluded the
updated_at fields as we are not going to use them in the frontend.
Serializer takes care of converting the model to json. We also need to add one or more views which will return the data once certain URL is provided. You could, for example, create a view which represents individual photo, or a view which represents a list of all photos. For our small application, the list view will be exactly what we are going to use.
In the file
from rest_framework import generics from pixies.photos.models import Photo from pixies.photos.serializers import PhotoSerializer class PhotosListView(generics.ListAPIView): queryset = Photo.objects.all() serializer_class = PhotoSerializer
Observe how DRF provides the generics.ListAPIView which needs to be just configured with the serializer and the query which retrieves the data we care about. In our case, it is just a list of all photos.
The last part of setting our Rest API is to provide the way to map the particular URL to the view we just created. Recall that when we scaffolded the Django project, it created a
pixies/urls.py file which is the map of all URLs our backend app is aware of. At the moment it has only an entry for the admin. We could have hook our PhotosListView right there, but it is considered a good practice to keep the urls which belong to different Django apps separately (remember, the Django project is made of apps and the
photos is the app)
So create a file
pixies.photos.urls with the following
from django.urls import path from .views import PhotosListView urlpatterns = [path("", PhotosListView.as_view())]
It says essentially, as far as the photos app is concerned, always return the PhotosListView.
The next step is to wire this into the central
pixies.urls.py. Make it look like this:
from django.contrib import admin # add include to imports from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), # new path("api/", include("pixies.photos.urls")), ]
This map says, that when Django sees the prefix
admin/, it will ask built-in admin to handle it.
But when it sees the prefix
api, it will let the
photos app to take care of it. As you remember, that always returns just the list of all photos.
All right, we are ready to try it. Make sure your Postgres container is running and run the backend:
python manage.py runserver
Navigate to the http://localhost:8000/api/ and you should see the page generated by the DRF which shows the json document with the list of our photos. If you want to see the raw json as our frontend would see, click on the select
json from the menu on the
Before we move on, one note - since we added custom URLs, the Django won’t generate the welcome page on the http://localhost:8000/. That is ok, we won’t be using that.
api are the only two endpoints we are going to need.
In the next module, we are going to containerize our backend