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 settings.py
:
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 pixes/photos.serializers.py
enter
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 id
, caption
and details
. Notice that we excluded the created_at
and 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 pixies/photos/views.py
do
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 GET
button.
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. admin
and api
are the only two endpoints we are going to need.
In the next module, we are going to containerize our backend