REST API with Django rest framework with React as front-end and postgresql as backend - 2


Hello and welcome back!!

In part 1, I created the database table, the model in django, serialized it, described a viewset and set up my routers. Lastly, I used postman to check if the API works fine.

This is part 2 of my attempt to show the college exam schedules from my postgreSQL database onto my react front-end via Django REST API framework.

I will now proceed to share Step 2 of the process where I create the React App and integrate it with the framework.

Step 2 - The React App

I have not used the standard create react app because I will be integrating react in the django app. Instead, I will be using django to create another app within the same project, and will be using the django template features which will act as our front-end. Traversy's video helped me understand how to do this. 

1. In the terminal of my backendproject folder, I create the app called frontend.
    prompt> manage.py startapp frontend
    This will create a frontend folder with the standard django files. 

2. I created required folders for react files.
Since we have not used standard create react app command, we will create the necessary files and folders manually.   Inside the frontend folder, I created the following folders
    1. frontend/src/components - to hold all source codes for the react app. 
    2. frontend/static/frontend - to hold compiled javascript.
    3. frontend/templates/frontend - to handle index.html file that will get loaded.

3. Install all required libraries.
    From the root folder (above the project folder) at the terminal,
   1. npm init -y
   This will create the package.json file in your root folder, which will list all dependencies.

    2. npm i -D webpack webpack-cli
   -D specifies installation as a dev dependency. Webpack bundles JavaScript applications. It takes modules with dependencies and generates optimized bundles that can be loaded by the browser. Webpack-CLI is used to interact with webpack. These should get listed in the package.json file under "devDependencies".

    3. npm i -D @babel/core babel-loader @babel/preset-env @babel/preset-react babel-plugin-transform-class-properties
babel is a transpiler (transforms source to another source) so that today's version of javascript can run in older browsers.

    4. npm i react react-dom prop-types
These are react libraries.

We have now installed all required libraries. I confirm these installations in the package.json file.

4. Configure application 
    1. To be able to use the babel libraries, I created a file called '.babelrc' in the project folder.  It is just a JSON object. This are its contents.
{
    "presets": ["@babel/preset-env","@babel/preset-react"],
    "plugins":["transform-class-properties"]
}

2. Create a webpack.config.js file in the project folder. We just want to load the babel module loader here.

Webpack configs allow you to configure and extend Webpack's basic functionality. A Webpack config is a JavaScript object that configures one of Webpack's options. Most projects define their Webpack config in a top-level webpack.config.js file. Text Courtesy:@masteringjs.io

Here is the structure and contents of the file:
We are specifying a rule here. The rule is to use the babel loader as a transpiler for any file with .js extension, and exclude  node_modules. 

module.exports =  {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            }
        ]
    }
}

3. Edit package.json file from: 

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

to:

 "scripts": {
    "dev": "webpack --mode development ./frontend/src/index.js --output-path ./frontend/static/frontend",
    "build": "webpack --mode production ./frontend/src/index.js --output-path ./frontend/static/frontend"
  },

./frontend/src/index.js - The entry point for our application.
./frontend/static/frontend/main.js - will contain the actual compiled javascript that we will include in our index.html file.

use npm run dev when running in dev mode, and npm run build when running in production mode.

**********************************************************************************************************************
This is how my folder structure looks like: (Sharing only important files and folders for reference)

backend>
    backendproject>
        __init__.py
        asgi.py
        settings.py
        urls.py
        wsgi.py
    backendapp> 
    frontend>
        migrations>
        src>
            components>
                App.js
        index.js
        static>
            app>
                main.js ---->   (Created by build)
        templates>
            app>
                index.html
    manage.py
    package.json
    package-lock.json
    .babelrc
    webpack.config.js
*****************************************************************************************

4. The Application Components Code

We will now look into all the code components that will run together as our app.

4.1 Our entry point is backendproject/frontend/src/index.js.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./components/App";

const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

4.2 This app is defined in backendproject/frontend/src/components/App.js

import React from 'react';

class App extends React.Component {
    render() {
        return <h1>React-App</h1>
    }
}
export default App;


4.3 Now, when the application runs, it is going to look at the backendproject/frontend/templates/frontend/index.html file the first thing. 

Starting with a standard html template.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
</body>
</html>

Change the title to show Schedules as the title.

In the body tag, include django templates from the static folder. Since this is a django template, we include the template tags %% notation. When we run npm run dev or npm run build, it will compile and create the backendproject/frontend/static/main.js file. This file is what will be used for running the entire app. "load static" will help include any other django templates in the static folder.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Schedules</title>
</head>
<body>
   <div id="app"></div>
   {%load static%}
   <script src="{% static "frontend/main.js" %}"></script>
</body>
</html>

Now, I will include the Zephyr UI theme that I like from bootswatch.com. In bootswatch.com, I select the UI theme, right-click on the download button and open up the link in a new page. I grab the url and include it in the link tag like so:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://bootswatch.com/5/zephyr/bootstrap.min.css">
    <title>Schedules</title>
</head>
<body>
   <div id="app"></div>
   {%load static%}
   <script src="{% static "frontend/main.js" %}"></script>
</body>
</html>

Since I need the javascript bootstrap files, I will include the bootstrap CDN link.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- Optimize code for mobiles using viewport -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://bootswatch.com/5/zephyr/bootstrap.min.css">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <title>Schedules</title>
</head>
<body>
   <div id="app"></div>
   {%load static%}
   <script src="{% static "frontend/main.js" %}"></script>
   <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>

4.4 Include this in the django framework.
4.4.1 In backendproject/settings.py, in the INSTALLED_APPS section, include the app

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
    'rest_framework',
    'frontend'
]
STATIC_URL = 'static/'

4.4.2 In backendproject/frontend/views.py, 

from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request,'frontend/index.html')

when you create a view method, pass in a request. render takes in the request, and renders output in the templates/frontend/index.html

4.4.3 Associate a url with the view method we just created.

in backendproject/frontend, create a file - urls.py

from django.urls import path
from . import views
urlpattern=[
    path('',views.index)
]

4.4.4 Include this url in the bacckendproject url. 

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

urlpatterns = [
    path('', include('app.urls')),
    path('admin/', admin.site.urls),
]


With this, we are ready to test it on our server.
5. Testing the Site to confirm everything is working properly.
5.1 From the project terminal, 
        npm run build.
        Confirm that this created the main.js file in static/frontend folder.
5.2 From the same terminal,
        manage.py runserver
This will run the app on localhost:8000. 
Visit the site and see what shows up:

Here is the output on the server



In Part 3, we will work on the react files to display the schedules from the database, using the API.


Comments