Create a Website using Django and React

In this tutorial, we will show you how to create a complete website using Django for backend and React for frontend.

Django is an open-source high-level Python Web framework that encourages rapid development and clean, pragmatic design. While React is also an open-source, Javascript library which makes it easier for building interactive UI components or user interfaces.

You should have some familiarity with HTML, Javascript and Python but you should be able to follow along even if you are coming from a different programming language.

Follow the steps below to complete this tutorial:

Create Project

The first thing you need to do is create your project folder:


mkdir my-project

Navigate inside the newly created project folder.


cd my-project

Inside the project folder, create two folders: backend and frontend.


mkdir backend

mkdir frontend

Setup Python Django For Backend

Navigate inside the backend folder:


cd backend

Create Python virtual environment inside the backend folder:


virtualenv env

Activate the Python virtual environment:


source env/bin/activate

Install Django:


pip3 install Django==3.1.6

Install MySQL client :


pip3 install mysqlclient

Install djangorestframework:


pip3 install djangorestframework

Create a Django project inside the backend folder using the command django-admin startproject yourprojectname :


django-admin startproject mydjangoproject

Rename the newly created Django project folder name to src

Open your project in Visual Code or any other Web development IDE that supports Python and React.

Navigate inside the src folder and create a model using the command python manage.py startapp model_name :


python manage.py startapp my_model

Open the /appname/settings.py file and add 'rest_framework', and the model name you just created 'my_model' in INSTALLED_APPS array as shown in the example below:


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'my_model'
]

Next, add the code below at the bottom of the /appname/settings.py file:


REST_FRAMEWORK = {
    # Use Django's standard 'django.contrib.auth' permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ],
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
        'rest_framework.throttling.ScopedRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '60/minute',

        'user': '100/day',
        '/api/get-items': '100000/day'
    },
}

Now, replace the database configuration for connecting with MySQL database in the /appname/settings.py file. Do not forget to replace the configuration values to make them relevant with your project:


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'my_database_name',
        'USER': 'root',
        'PASSWORD': 'Testing123',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

Next, open /appname/urls.py file and add path('api-auth/', include('rest_framework.urls')) to urlpatterns. The following listing shows how to do so:


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls'))
]

Navigate inside the newly created model folder and add your model class to src/my_model/models.py file. The following listing shows how to do so:


from django.db import models

# Create your models here.

class MyProduct(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.TextField()
    product_code = models.TextField()
    visibility = models.BooleanField(blank=True)
    currency_type = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    requester_ip = models.GenericIPAddressField(null=True, blank=True)
    created_date = models.DateTimeField(auto_now_add=True)

Now run the following migration script from inside the src folder:


python manage.py makemigrations
python manage.py migrate

Next, create a api folder inside the src/my_model/ model folder.

Inside the api folder, create __init__.py, serializers.py, urls.py, views.py files.

Let's serialize our model MyProduct class in src/my_model/api/serializers.py . The following shows how to do so:


from rest_framework import serializers
from my_model.models import MyProduct

class MyProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = MyProduct
        fields = ('id',
                  'name',
                  'product_code',
                  'visibility',
                  'currency_type',
                  'price',
                  'requester_ip',
                  'created_date')

Create APIs in the src/my_model/api/views.py file to call from our frontend later. The following listing shows how to do so:


from rest_framework.generics import ListAPIView

from .serializers import MyProductSerializer
from my_model.models import MyProduct
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework import permissions


@api_view(['POST'])
@permission_classes((permissions.AllowAny,))
def add_product(request):
    ip = get_client_ip(request)
    serializer = MyProductSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save(requester_ip=ip)
    return Response(serializer.data)


def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

Next, open src/my_model/api/urls.py and the API functions. The code below shows how to do so:


from django.urls import path
from . import views

urlpatterns = [

    path('', views.add_product,
         name="add_product")
]

Now, open the main backend/src/my_project_name/urls.py file and add url to urlpatterns. The following code shows how to do so:


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),
    path('api/products', include('my_model.api.urls'))
]

Next, install django-cors-headers. Adding CORS allows your resources to be accessed from other domains:


pip3 install django-cors-headers

Then open backend/src/myappname/settings.py and add the django cors headers to install apps:


INSTALLED_APPS = [
    ...
    ...
    'corsheaders',
]

You will also need to add a middleware class 'corsheaders.middleware.CorsMiddleware' , 'django.middleware.common.CommonMiddleware' to listen in on responses. Example:


MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',

    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
]

The 'corsheaders.middleware.CorsMiddleware' should be placed as high as possible, before any middleware which can generate responses such as Django's CommonMiddleware or WhileNoise's WhiteNoiseMiddleware. If not placed before, it will not be able to add the CORS headers to these responses.

Also, allow CORS for all requests by adding the following at the bottom of backend/src/myappname/settings.py file:


CORS_ORIGIN_ALLOW_ALL = True

From inside the backend/src directory run your backend using the following command:


python3.9 manage.py runserver 5000

You can access the backend REST APIs at http://localhost:5000/api/

Setup React For Frontend

To setup React for the frontent development, navigate inside the frontend folder:


cd frontend

Create react project folder inside the frontend folder:


npx create-react-app gui

Navigate inside the gui folder.


cd gui

Install react-router-dom latest version. The react-router-dom provides methods to navigate between different components, changing the browser URL, modifying the browser history, and keeping the UI state in sync.


npm install react-router-dom

Next, open frontend/gui/src/index.js file and route "/" to App component. The following listing shows how to do so:


import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter, Route, Switch } from "react-router-dom";

ReactDOM.render(
  <React.StrictMode>
  <BrowserRouter>
   <Switch>
    <Route exact path="/" component={App} />
    </Switch>
    </BrowserRouter>
    </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();

Install Bootstrap latest version:


npm install [email protected]

Next, open frontend/gui/src/App.css file and remove everything in it.

Open frontend/gui/src/index.js file and import 'bootstrap/dist/css/bootstrap.min.css' . The following listing shows how to do so:


import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
     <Switch>
       <Route exact path="/" component={App} />
     </Switch>
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();

Install axios. The axios is a promised based HTTP client:


npm install axios

Now, replace the code of frontend/gui/src/App.js with the following:



Create a frontend/gui/src/components folder where you can create and keep your React components.

Start the frontend.


npm start