Building a Django-React book-tracking app: the backend setup
A step-by-step guide at how to set up a Django backend using the Django REST framework to integrate with a React frontend
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:
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:
Navigate into that directory:
Then, install Pipenv using either
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:
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:
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 —
You can quit the server at any point with
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.
Navigate to your
models.py file located within the booktracker app folder.
last_nameare 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
CharFieldoption indicates that the column’s datatype is a string, requiring a
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
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
ForeignKeyclass to refer to the associated author instance. This class requires two arguments: the class to which the model is related and the
on_deleteoption, which will delete the model instance (i.e. book) if the related model instance (author) is deleted.
TextFieldis also a string field, but for larger amounts of data
readfield requires the
BooleanFieldclass type, which can take a default argument. If no default is given, the default value of
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:
list_displayto 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 ‘
INSTALLED_APPS list in the
Then, to tell the frontend (served on port 3000) to interact with this API, add the following to the bottom of the
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
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
idproperty 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
AuthorSerializerclass, 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:
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:
viewsets base class provides the implementation for CRUD operations by default, and specifies the
queryset. ViewSets are helpful to get an app up and running quickly, since repeated logic can be combined into a single class.
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
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
adminpath was already included for us).
urlpatternsvariable 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:
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!