How to Integrate Django with React: Building a Planet Catalog App
Repository 📖: Link
In this tutorial, we will walk through the process of integrating Django, a high-level Python web framework, with React, a popular JavaScript library for building user interfaces. Our goal is to create a simple Django REST API that serves planet names and then build a React application to display these planets on the screen. By following this guide, you'll learn how to leverage the power of Django for backend development and React for frontend development to create a seamless full-stack application.
In our Visual Studio Code, let's create a folder called Solar System App and develop our code inside of it.
In our project, we'll divide it into two parts. In the first one, we'll handle the Django backend, while in the second one, we'll create our frontend with ReactJS. For this, we should create a folder in our directory for each of the parts.
Part 1: Creating a Django REST API
1.1. Setting up a Django project:
First of all, you need to make sure that you have Python installed on your machine. If you don't, follow this tutorial and install the language on your computer.
We should open our integrated terminal where we'll input our commands. We can do this by typing the shortcut ctrl + shift + '
or by going to the top menu bar of our VS Code and selecting terminal > New Terminal:
Enter the backend directory by typing cd backend
in the terminal, and then run the following command to install the Django library:
pip install django
We will also need the following libraries:
pip install djangorestframework django-cors-headers
To create the boilerplate of our Django application, we should run the following command:
django-admin startproject setup .
This way, we'll be ready to test our application on our localhost by running the following code:
Windows:
python manage.py runserver
Mac or Linux:
python3 manage.py runserver
And voilà, by accessing the link, we'll have our application up and running.
1.2. Defining a Planet app and model:
Time to create our application for our planets along with its model.
In Django, applications are like modular building blocks, each with a specific function within the project. They promote code reusability, facilitate maintenance, and enable project scalability. By dividing the application into independent and interconnected parts, applications simplify development and promote collaboration among developers.
Run the following command:
python manage.py startapp planets
So far, this is how the structure of our project should look like:
We should also create a model for our planets. In Django, models are like forms for our application. They tell us what type of information our application will store and how this information is organized.
It's like a table where we jot down all the important things about our data, like name, age, etc. This helps us organize and access our information easily and efficiently.
Go to backend/planets/models.py and paste the following code on the file:
from django.db import models
class Planets(models.Model):
name = models.CharField(max_length=255, default=False)
We should add our newly created app to the list of applications in our setup. We can do this by going to setup/settings.py and adding the name of our app to the array called INSTALLED_APPS.
We also need to add the libraries we downloaded to our project to our file.
Your file should look like this.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'planets',
'rest_framework',
'corsheaders',
]
We must also add three extra rows on settings.py
MIDDLEWARE = [
# ...
# 👇 Add this line here
'corsheaders.middleware.CorsMiddleware',
# Add above line just before this line 👇
'django.middleware.common.CommonMiddleware',
]
# 👇 Add this line here
CORS_ORIGIN_ALLOW_ALL = True
1.3. Populating the database:
Now that we have our application and model created, we can populate our database with our planets. But before that, we need to migrate our newly created model.
In Django, migrations are like instructions for the database. When we change the structure of our models (for example, by adding a new field), we need to inform the database about these changes. Migrations are these instructions that make the necessary changes in the database to reflect the changes in our models.
It's like a to-do list to ensure that the database is always up-to-date with our application. We can do this by running the following commands:
Windows:
python manage.py makemigrations
python manage.py migrate
Mac or Linux:
python3 manage.py makemigrations
python3 manage.py migrate
Though there are more orthodox ways to add items to the database, let's choose the best one: through the Django admin dashboard.
In Django, the admin dashboard is like a control room for your website. It's an area where you can manage all the data of your application easily and quickly, without needing to directly touch the database or the code.
It's like a control panel that allows you to add, edit, or delete data from your site, such as users, blog posts, or any other information your application manages. It's a powerful tool for site administrators, making the management and maintenance of the application easier.
We should create a user to access the dashboard. We can do this by running the following command:
python manage.py createsuperuser
After filling in the required information through the terminal, we can log into our panel through the link:
Notice that after logging in with the information we just entered, we can't find our Planet model. To fix this, we should paste the following snippet of code into backend/planets/admin.py:
from django.contrib import admin
from planets.models import Planet
@admin.register(Planet)
class PlanetAdmin(admin.ModelAdmin):
list_display = [
"name"
]
search_fields = [
"name"
]
After this, we should be able to add our planets to the database in a much simpler and faster way!
1.4. Creating a REST API:
Before we create our frontend, it's necessary to prepare our API routes to be consumed. We should perform the following tasks for this.
- Create a serializer.
- Define a view to our planets.
- Define a api route.
1.4.1. Planet Serializer Class
In Django, a serializer class is responsible for converting complex objects, such as database models or other types of data, into simpler and more accessible formats, such as JSON. It allows data to be easily transmitted over the network or stored in a structured way.
It's like a translator that converts information into a language that computers and other systems can easily understand and manipulate. Serializer classes are useful in RESTful APIs, where we need to send or receive data efficiently and in a standardized manner.
Within the planets app directory, create a file named serializers.py and paste the following code into it:
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Planet
class PlanetSerializer(serializers.ModelSerializer):
class Meta:
model = Planet
fields = ["id", "name"]
1.4.2. Planet View Class
In Django, a view class is like a set of instructions that determines how a web page will be displayed. It defines the logic behind rendering a page, handling user requests, and returning an appropriate response.
It's like the brain behind the interface of your web application, deciding what to show to the user based on the received requests. View classes are often used to control user interaction with the application, processing data, performing operations, and sending dynamic responses.
Inside backend/planets/views.py paste the following code:
from django.shortcuts import render
from rest_framework import generics
from planets.models import Planet
from planets.serializers import PlanetSerializer
class PlanetsListCreate(generics.ListCreateAPIView):
serializer_class = PlanetSerializer
queryset = Planet.objects.all()
Note that we're importing our serializer and using it to convert the rows coming from the database into a JSON object.
1.4.3. Api URL
Finally, it's time to create the URL for the API that will be consumed by the frontend. Go to backend/setup/urls.py and add the following snippet to your urlspatterns:
path('api/planets/', views.PlanetsListCreate.as_view(), name='planets'),
Your final code should look like this:
from django.contrib import admin
from django.urls import path
from planets import views
urlpatterns = [
path('admin/', admin.site.urls),
path('api/planets/', views.PlanetsListCreate.as_view(), name='planets'),
]
1.5. Testing the API:
Django REST Framework (DRF) is a powerful library that extends Django's capabilities to facilitate the creation of RESTful APIs. It provides additional tools and resources for developing APIs quickly and consistently, including serializers, authentication, permissions, and class-based views. DRF simplifies the implementation of CRUD operations (Create, Read, Update, Delete) and provides a flexible framework for developing robust and scalable APIs in Django.
It's like a complete toolbox for building modern and efficient web APIs with Django.
By accessing the following link, we can see our added planets.
Part 2: Building a React + Vite App
Let's move to our frontend directory to create our ReactJS app. We first need to run the following commands on the backend terminal.
cd ../
cd frontend
2.1. Setting up a React project with Vite:
Let's move to our frontend directory to create our ReactJS app. We first need to run the following commands on the backend terminal.
For creating our app, let's choose a different approach from the most common, let's use vite. Vite.js is a build tool that is designed to be fast and lightweight. It uses native ES modules and a native development server to provide a fast and seamless development experience. Vite.js also supports code splitting and hot reloading.
Let's run the command:
npm create vite@latest .
Choose React as framework
Let's also choose Javascript instead of TypeScript so we can keep things simple.
Finally we must run these commands:
npm install
npm run dev
And open our browser on this link and then we have our running React app.
2.2. Creating our table component
Within the frontend/src
folder let's create our table component. ReactJS apps don't have a component folder by default so don't forget to create it.
Your frontend structure will look like this:
Before actually creating our component, let's add the tailwind CDN to our frontend/index.html file, thus we will have an highly customized app without really getting into CSS on this article.
Tailwind CDN:
<script src="https://cdn.tailwindcss.com"></script>
Your index.html will look like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Back to our table.jsx file, paste this snippet of code into it:
import { useState } from "react"
const Table = () => {
const [planets, setPlanets] = useState([])
return (
<div className="flex flex-col w-[400px] absolute top-1/2 left-1/2 transform translate-x-[-50%] translate-y-[-50%]">
<div className="overflow-x-auto sm:mx-0.5 lg:mx-0.5">
<div className="py-2 inline-block min-w-full sm:px-6 lg:px-8">
<div className="overflow-hidden">
<table className="min-w-full border">
<thead className="bg-white border-b">
<tr>
<th scope="col" className="text-sm font-medium text-gray-900 px-6 py-4 text-left">
#
</th>
<th scope="col" className="text-sm font-medium text-gray-900 px-6 py-4 text-right">
Planet
</th>
</tr>
</thead>
<tbody>
{
planets.map((item)=> (
<tr key={item.id} className="bg-gray-100 border-b [&:nth-child(even)]:bg-white">
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{item.id}</td>
<td className="text-sm text-gray-900 font-light px-6 py-4 whitespace-nowrap text-right">
{item.name}🪐
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
</div>
</div>
)
}
export default Table
So far, your app must look like this:
Notice the table is empty since we are not fetching any data yet.
2.3. Fetching planets from Django
With our backend Django app running on port 8000. (don't forget to run python manage.py runserver
on backend terminal), we are good to get data from our database through an api function we will build now.
In order to request data, we must install a lib called axios which will do the hard work for us. Run the following command on frontend terminal:
npm install axios
Our api function will be placed on the utils folder within frontend/src, after creating this directory, paste the following code on the api.js file:
import axios from 'axios';
export async function api() {
let url = `http://127.0.0.1:8000/api/planets/`;
const res = await axios.get(url);
return res.data;
}
We will run this function on our table.jsx inside of a useEffect and store its value on our useState. Don't forget to import these hooks.
import { useEffect, useState } from "react"
import { api } from "../utils/api"
const Table = () => {
...
useEffect(()=>{
const getPlanets = async () => {
let results = await api()
setPlanets(results)
}
getPlanets()
}, [])
...
By saving our file, the planets will be rendered as a magic trick on the screen.
Conclusion:
By following this step-by-step guide, you've learned how to integrate Django with React to build a full-stack web application. You've created a Django REST API to serve planet data and built a React frontend to display this data to users. This tutorial demonstrates the power of combining Django's robust backend capabilities with React's flexible frontend framework. Experiment with additional features and functionalities to further enhance your application!