Building a Django-React book-tracking app: the backend setup

Sara Bastian
Geek Culture
Published in
7 min readJun 28, 2021

--

A step-by-step guide at how to set up a Django backend using the Django REST framework to integrate with a React frontend

Photo by Florencia Viadana on Unsplash

After getting warmed up with Django by making a simple to-do app using React, I wanted to level up slightly and learn how to use more than one model — to begin to understand how larger projects with more relational data tables are handled. Follow along to learn how to get a Django API with a one-to-many model relationship up and running.

What You’ll Need

You will need to have Python 3 and Node.js installed — follow the links below to download both according to your local environment:

Python installation

Node.js installation

Creating the Project

First, navigate to the directory you’ll want to host the entire application and enter the following command to make a new project:

mkdir django-react-booktracker

Navigate into that directory:

cd django-react-booktracker

Then, install Pipenv using either pip or pip3 depending on your download:

pip install pipenv 

Pipenv automatically builds and manages a virtual environment for your project, so each Python project you build can have its own dependencies (like Django), which you will not have to install globally.

To activate the virtual environment, always use the below command:

pipenv shell

Next, install Django in your virtual environment using pipenv:

pipenv install django

Now, you can create a new project and name it backend:

django-admin startproject backend

And, navigate into the backend folder:

cd backend

Next, create a new application within the backend project called booktracker:

python manage.py startapp booktracker

**Apps and projects are not interchangeable in definition or practice; a project can have multiple apps. For instance, a single project can have a blog and a book- tracker, but both should be created as separate apps.

Run initial migrations:

python manage.py migrate

And, finally, your server can be started at any time by entering the following into your virtual environment:

python manage.py runserver

You should see the below image if all went as expected —

View of Django server after installation
source: https://djangoforbeginners.com/hello-world/

You can quit the server at any point with CONTROL+C.

Register the application

Although the necessary files and dependencies for the booktracker app have been installed, Django does not yet register it unless we add it into the INSTALLED_APPS list in the settings.py folder, located in the backend folder.

Creating the Models

Models provide the logical structure of the entire app, represented by a database. Each model maps to a database table. For a simple booktracking app, the two most obvious, or necessary, data tables include Book and Author.

Author Model

Navigate to your models.py file located within the booktracker app folder.

  • first_name and last_name are the properties, or fields, of the Author model, which are specialized as class attributes and mapped to their respective column in the database.
  • Each field is an instance of the relevant Field class, which is used to determine the datatype of the column and any validation requirements. The CharField option indicates that the column’s datatype is a string, requiring a max_length argument.

After creating this model, create a migration file and then run the migration for the Author model:

python manage.py makemigrations author
python manage.py migrate author

Book Model

After these migrations are complete, set up the Book model in the same models.py file like so —

A couple things to note in this class:

  • Since a book has/belongs to an author and an author can have many books, we can represent this many-to-one relationship with the ForeignKey class to refer to the associated author instance. This class requires two arguments: the class to which the model is related and the on_delete option, which will delete the model instance (i.e. book) if the related model instance (author) is deleted.
  • The TextField is also a string field, but for larger amounts of data
  • The read field requires the BooleanField class type, which can take a default argument. If no default is given, the default value of BooleanField is None

Again, you’ll need to make a migration file and run the migration for this second model:

python manage.py makemigrations book
python manage.py migrate book

Create the admin interface

An added feature of Django is its admin interface, which is essentially an internal management tool trusted users can use to handle the database. The admin interface gives automatic access to the core CRUD functionality to manage data.

Setting up this service is easy: open the admin.py file ( booktracker/admin.py) and add the following code:

  • Set list_display to the model properties to control which fields are displayed on the change list page of the admin.

To gain access to the admin site, create a superuser with the following command:

python manage.py createsuperuser

This command will prompt you to enter an email and create a username and password for the admin user. Once you have done so, start the server (python manage.py run server) and navigate to http://localhost:8000/admin; you will be prompted to login and then should see a page similar to the following:

You can now add new author and book instances, as well as review, edit, or delete existing instances.

Set up the APIs

To allow users to retrieve and manage data via requests on the browser side, we need to set up an API to allow this interaction with the database.

Run the following command in the Django virtual environment to get started with building the Web API:

pipenv install djangorestframework django-cors-headers

Once you have installed that from the command line, add both ‘corsheaders’ and ‘rest_framework’to the INSTALLED_APPS list in the settings.py file.

Then, to tell the frontend (served on port 3000) to interact with this API, add the following to the bottom of the settings.py file:

Serializers

Serializers are necessary for converting model instances and SQL to JSON, which is the representation of data sent via HTTP requests between the frontend & backend.

Create a new file in the booktracker app directory and name it serializers.py (so from the root of the project, that should be located as booktracker/serializers.py).

Import the serializers base class from the Django REST framework, as well as all models, and make a serializer class for each model.

  • Make sure to include the id property when defining the fields, as that will be necessary for eventually accessing, updating, or deleting resources on the client-side.
  • We want the associated author instance to appear in the JSON format for a book’s resource. To do that, set a variable of author equal to the already defined AuthorSerializer class, taking two arguments: many=False (author instance is one-to-many books) and read_only=True (we don’t need the option to change the author here). The data for the author will be an object/dictionary in JSON format, and will be nested within a particular book’s resource, like so:
http://localhost:8000/api/books/

Views

The purpose of the views file is to take an incoming Web request and return a Web response, which can be anything a Web page can display, such as the HTML contents, a redirect, etc.

Again in the booktracker app directory, open the views.py file and write the following code:

The viewsets base class provides the implementation for CRUD operations by default, and specifies the serializer_class and queryset. ViewSets are helpful to get an app up and running quickly, since repeated logic can be combined into a single class.

URLS

To handle incoming requests, the REST framework adds support for automatic URL routing, offering a quick and consistent way of wiring view logic to a set of URLs (that semantically make sense for the request).

Navigate to the urls.py file in the backend project directory (backend/urls.py), import the following modules, register each model router, and set the urlpatterns variable:

  • The register() method requires the two arguments: the prefix (the URL prefix to use for this set of routes), and the related viewset class. It can take a third optional argument, the basename, which is thebase to use for the URL names that are created(since the admin site is a built-in feature, the admin path was already included for us).
  • The urlpatterns variable acts as a step in URL dispatching, aiding to map between URL path expressions to Python functions (your views).

Now, we have full CRUD functionality set up for browser requests. The router class allows users to make queries to the api at the following endpoints:

  • localhost:8000/api/books and localhost:8000/api/authors return a list of all the books and authors, respectively. READ and CREATE actions occur at this endpoint
  • /api/books/id and /api/authors/id return a single book and author item, respectively. PUT/PATCH and DELETE actions occur at this endpoint.

That’s it! The API setup is now complete, and you are ready to start building the frontend, giving users access to making API calls to retrieve and manage their own summer reading list!

--

--

Sara Bastian
Geek Culture

full-stack developer exploring how software can solve real-world problems | https://sarabastian.com/