Djang Course File
Djang Course File
Djang Course File
Django
COURSE FILE
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
Programme UG
Branch CSE
Section A,B,C
E.satishBabu
CSE
Verified by :
Approved by:
HOD-CSE
Course File –Contents
S. No. Title
1 Syllabus Prescribed by University
2 Programme Educational Objectives (PEOs)
3 Programme Outcomes (POs)
Exercises:
1. Build a responsive web application for shopping cart with registration, login, catalog and cart
pages using CSS3 features, flex and grid.
2. Make the above web application responsive web application using Bootstrap framework.
3. Use JavaScript for doing client – side validation of the pages implemented in experiment 1 and
experiment 2.
4. Explore the features of ES6 like arrow functions, callbacks, promises, async/await. Implement
an application for reading the weather information from openweathermap.org and display the
information in the form of a graph on the web page.
5. Develop a java stand alone application that connects with the database (Oracle / mySql) and
perform the CRUD operation on the database tables.
6. Create an xml for the bookstore. Validate the same using both DTD and XSD.
7. Design a controller with servlet that provides the interaction with application developed in
experiment 1 and the database created in experiment 5.
8. Maintaining the transactional history of any user is very important. Explore the various sessions
9. Create a custom server using http module and explore the other modules of Node JS like OS,
path, event.
10. Develop an express web application that can interact with REST API to perform CRUD
operations on student data. (Use Postman)
11. For the above application create authorized end points using JWT (JSON Web Token).
12. Create a react application for the student management system having registration, login,
contact, about pages and implement routing to navigate through these pages.
13. Create a service in react that fetches the weather information from openweathermap.org and
the display the current and historical weather information using graphical representation using
chart.js
14. Create a TODO application in react with necessary components and deploy it into github.
REFERENCE BOOKS:
1. Jon Duckett, Beginning HTML, XHTML, CSS, and JavaScript, Wrox Publications, 2010
2. Bryan Basham, Kathy Sierra and Bert Bates, Head First Servlets and JSP, O’Reilly Media, 2nd
Edition, 2008.
3. Vasan Subramanian, Pro MERN Stack, Full Stack Web App Development with Mongo,
Express, React, and Node, 2nd Edition, A Press.
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
PEO1- To provide the learners with fundamental knowledge of applied mathematics, applied sciences
and basic engineering subjects to analyze and solve the problems in Computer Science and
Engineering and its allied fields.
PEO2 - To provide learners with a concrete knowledge in the Core areas like Programming languages,
Computer Organization & Architecture, Operating Systems, Networking, Database Management
Systems, Information & Network Security, Data Mining, etc. and with cutting edge technologies.
PEO3 –To nurture the learners with breadth subjects knowledge and competence in the areas of ES,
VLSI, cloud computing , BigData, Android, Multimedia, IM, Management Science, ENS etc. by
understanding the value of efficient design and development of solutions with multidisciplinary
approach catering to the real-time requirements
PEO4 –To inculcate the learners with advanced subjects knowledge, professional practice,
entrepreneurial skills, teamwork, leadership, project management, personal and professional growth
with ethics and character in developing effective communication, interpersonal and multidisciplinary
skills.
PEO5 –To prepare the learners for higher education, employability, innovative CSE program specific
areas of global technological appliances, research, and service attitude by providing advanced methods
of teaching and learning with effective communication & lifelong learning skills and by executing
MOUs with renowned industries and premier institutes.
.DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
PROGRAM OUTCOMES
PO1. Build a custom website with HTML, CSS, and Bootstrap and little JavaScript.
PSOs - CSE
PSO1: Graduates will demonstrate the knowledge in allied areas of Computer Science & Engineering.
PSO2: The learners will be able to gain desired knowledge for the Competitive Environment.
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
Course Objectives:
For Node JS/ React JS/ Django, the course will enable the students to:
To implement the static web pages using HTML and do client side validation using
JavaScript.
To design and work with databases using Java
To develop an end to end application using java full stack.
To introduce Node JS implementation for server side programming.
To experiment with single page application development using React.
Course Outcomes:
Upon completion of this course, the student will be able to:
CO1:Analyze algorithms and estimate their best-case, worst-case and average-case behavior in terms
of time and space complexity.
CO2:Design appropriate algorithm for solving problems using Divide and Conquer, Backtracking.
CO3:Identify the suitable data structures and algorithm designmethods impact the performance of an
algorithm using dynamic programming.
CO4:Apply algorithm design principles to derive solutions for real life problems using greedy method.
.
Mapping of Course Outcomes with Program Outcomes:
Name of the Subject: Node JS/ React JS/ Django
Regulation: R-22
Subj P P P P
Ye Se Subject ect CO P P P P P P P P P P O O S S
ar m Name Cod PO O O O O O O O O O O 1 1 O O
e 1 2 3 4 5 6 7 8 9 10 1 2 1 2
CO1 2 3 2 2 1 - - - - 2 2 2 2 3
CO2
2 3 1 2 1 - - - - 2 2 2 2 3
Node JS/
React CO3
II II ---- 2 2 2 2 1 - - - - 2 2 2 2 3
JS/
Django CO4
2 3 2 2 2 - - - - 2 2 2 2 2
CO5
2 3 2 2 2 - - - - 2 2 2 2 2
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
LESSON PLAN
First, we create a components folder; this houses our reusable components, for example, Navbar.
We will continue by setting up our user interface (UI) for the application. You can get all UI
components from WrapPixel’s UI Kit. WrapPixel is an online template store where you could get
great Free React Dashboard and React Bootstrap Templates.
We will add the bootstrap CDN to our root index.html file inside the public directory.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-
JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Shopping cart</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Then we add a Navbar.js file to the components folder. This is where we will handle our routing.
import "./App.css"
function App() {
return (
<div className='App'>
<Navbar />
<Switch>
// Our pages will go here
</Switch>
</div>
)
}
export default App
Secondly, we create a page folder. This folder houses our pages(product and cart page), all our
services and views will be rendered in the pages for routing.
Since we have it as an array now, we loop through it to display as seen on line 64.
We will also need to add items to the cart, which will be an async method making a request to the
backend with its parameters passed to it. This is a very important feature as well.
<button
onClick={(e) => addToCart(product._id, 1)}
className="btn btn-md btn-info"
>
Add to cart
</button>
Here, we pass the id of the product and a default quantity as 1.
import "./App.css"
function App() {
return (
<div className='App'>
<Navbar />
<Switch>
<Route exact path='/' component={Products} />
</Switch>
</div>
)
}
export default App
Let’s head over to the cart page and add our simple UI.
We then add a method to fetch a list of our cart items from the backend. Notice the fetchCart method
below. Doing as pleased.
If you are not familiar with react hooks, you could always look it up or better still use the component-
based.
Notice the increamentQty(id) the method which takes the product id as a parameter and then set
the quantity to one as default as we are updating the quantity by one.
<button
onClick={(e) => increaseQty(item.productId._id)}
className="btn btn-primary btn-sm"
>
+
</button>
Clicking on the button will increment the quantity of the item.
We then define an emptyCart the method as well to delete all items currently in the cart. See below;
2. Make the above web application responsive web application using Bootstrap framework.
<!
DOCTYPE
html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-
scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
footer{
margin-top: 60px;
background-color: pink;
padding-top: 40px;
}
.fa {
padding: 6px;
width: 35px;
text-align: center;
text-decoration: none;
margin: 5px 2px;
}
.fa-google-plus{
color: white;
background-color: #dd4b39;
}
.fa-facebook{
color: white;
background-color: #3B5998;
}
.fa-linkedin{
color: white;
background-color: #007bb5;
}
.fa-twitter{
color: white;
background-color: #55ACEE;
}
.fa-youtube{
color: white;
background-color: #bb0000;
}
</style>
</head>
<body>
<nav class="navbar navbar-dark navbar-expand-sm bg-primary
fixed-top">
<div class="container">
<button class="navbar-toggler" type="button" data-
toggle="collapse" data-target="#Navbar">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand mr-auto"
href="./index.html">InfoLabzz</a>
<div class="collapse navbar-collapse" id="Navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item active"><a class="nav-link"
href="./index.html"><span class="fa fa-home fa-lg"></span>
Home</a></li>
<li class="nav-item"><a class="nav-link"
href="./about.html"><span class="fa fa-info fa-lg"></span>
About</a></li>
<li class="nav-item"><a class="nav-link"
href="./contact.html"><span class="fa fa-address-card fa-
lg"></span> Contact</a></li>
</ul>
</div>
</div>
</nav>
<header class="jumbotron">
<div class="container">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12
col-xl-12">
<h1 class="text-center">Welcome to
InfoLabzz</h1>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
text-center" id="jumbo">
<button type="button" class="btn btn-success"><a
href="./addemp.html" style="text-decoration: none; color:
#FFFFFF">Add new employee</a></button>
</div>
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
offset-sm-2 offset-md-2 offset-lg-2 offset-xl-2 text-center"
id="jumbo">
<button type="button" class="btn btn-warning"><a
href="./modifyemp.html" style="text-decoration: none; color:
#FFFFFF">Modify an employee</a></button>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
text-center" id="jumbo">
<button type="button" class="btn btn-info"><a
href="./viewemp.html" style="text-decoration: none; color:
#FFFFFF">View an employee</a></button>
</div>
<div class="col-12 col-sm-5 col-md-5 col-lg-5 col-xl-5
offset-sm-2 offset-md-2 offset-lg-2 offset-xl-2 text-center"
id="jumbo">
<button type="button" class="btn btn-danger"><a
href="./delemp.html" style="text-decoration: none; color:
#FFFFFF">Delete an employee</a></button>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-4 col-sm-3 col-md-3 col-lg-3 col-
xl-3">
<h5>Links</h5>
<ul class="list-unstyled">
<li><a href="./index.html">Home</a></li>
<li><a href="./about.html">About</a></li>
<li><a
href="./contact.html">Contact</a></li>
</ul>
</div>
<div class="col-8 col-sm-6 col-md-6 col-lg-6 col-
xl-6 text-center">
<h5>Our Address</h5>
<address>
121, Clear Water Bay Road<br>
<i class="fa fa-phone fa-lg"></i> +91-
908567896<br>
<i class="fa fa-fax fa-lg"></i> +91-
908567896<br>
<i class="fa fa-envelope fa-lg"></i> <a
href="mailto:[email protected]">[email protected]</a>
</address>
</div>
<div class="col-12 col-sm-3 col-md-3 col-lg-3 col-
xl-3">
<h5 class="text-center">Connect with us</h5>
<div class="text-center">
<a href="http://google.com/+"><i class="fa
fa-google-plus fa-lg"></i></a>
<a
href="http://www.facebook.com/profile.php?id="><i class="fa fa-
facebook fa-lg"></i></a>
<a href="http://www.linkedin.com/in/"><i
class="fa fa-linkedin fa-lg"></i></a>
<a href="http://twitter.com/"><i class="fa
fa-twitter fa-lg"></i></a>
<a href="http://youtube.com/"><i class="fa
fa-youtube fa-lg"></i></a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<p>© Copyright 2020 <a
href="./about.html">InfoLabzz Pvt. Ltd.</a></p>
</div>
</div>
</div>
</footer>
<!-- jQuery first, then Popper.js, then Bootstrap JS. -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+Ibb
VYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.
min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZ
p6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap
.min.js" integrity="sha384-
w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
crossorigin="anonymous"></script>
</body>
</html>
3.Use JavaScript for doing client – side validation of the pages implemented in experiment 1 and
experiment 2.
form>
<p>
<fieldset>
<legend>Do you have a driver's license?<span aria-label="required">*</span></legend>
<!-- While only one radio button in a same-named group can be selected at a time,
and therefore only one radio button in a same-named group having the "required"
attribute suffices in making a selection a requirement -->
<input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label>
<input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
</fieldset>
</p>
<p>
<label for="n1">How old are you?</label>
<!-- The pattern attribute can act as a fallback for browsers which
don't implement the number input type but support the pattern attribute.
Please note that browsers that support the pattern attribute will make it
fail silently when used with a number field.
Its usage here acts only as a fallback -->
<input type="number" min="12" max="120" step="1" id="n1" name="age"
pattern="\d+">
</p>
<p>
<label for="t1">What's your favorite fruit?<span aria-label="required">*</span></label>
<input type="text" id="t1" name="fruit" list="l1" required
pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
<datalist id="l1">
<option>Banana</option>
<option>Cherry</option>
<option>Apple</option>
<option>Strawberry</option>
<option>Lemon</option>
<option>Orange</option>
</datalist>
</p>
<p>
<label for="t2">What's your email address?</label>
<input type="email" id="t2" name="email">
</p>
<p>
<label for="t3">Leave a short message</label>
<textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
</p>
<p>
<button>Submit</button>
</p>
</form>
Copy to Clipboard
form {
font: 1em sans-serif;
max-width: 320px;
}
p > label {
display: block;
}
input[type="text"],
input[type="email"],
input[type="number"],
textarea,
fieldset {
width: 100%;
border: 1px solid #333;
box-sizing: border-box;
}
input:invalid {
box-shadow: 0 0 5px 1px red;
}
input:focus:invalid {
box-shadow: none;
}
4. Explore the features of ES6 like arrow functions, callbacks, promises, async/await. Implement
an application for reading the weather information from openweathermap.org and display the
information in the form of a graph on the web page.
5. Develop a java stand alone application that connects with the database (Oracle / mySql)
and perform the CRUD operation on the database tables.
CRUD stands for Create, Read/Retrieve, Update and Delete and these are the four basic
operations that we perform on persistence storage. CRUD is data-oriented and the
standardized use of HTTP methods. HTTP has a few methods which work as CRUD
operations and do note they are very vital from a developmental point perspective in
programming that also does helps us relate better web development and also aids us while
dealing with databases.
So, standard CRUD Operations is as follows:
POST: Creates a new resource
GET: Reads/Retrieve a resource
PUT: Updates an existing resource
DELETE: Deletes a resource
MySQL Database
MySQL is an RDBMS (Relational Database Management System) based on the SQL
(Structured Query Language), which is the popular language for accessing and managing
the records in the database. MySQL is open-source and free software under the GNU
license. It is supported by Oracle Company. The data in a MySQL database are stored in
tables. A table is a collection of related data, and it consists of columns and rows. Some of
the features of MySQL are listed below:
1. It is a database system used on the web
2. It runs on a server
3. It is ideal for both small and large applications
4. It is very fast, reliable, and easy to use
5. It uses standard SQL
6. It is free to download and use
So to connect and perform CRUD operation with the MySQL DB with Spring Boot
application we have to just configure it inside the application.properties file as follows:
spring.datasource.url = jdbc:mysql://localhost:3306/schooldb
(Datasource URL of your DB and "schooldb", here is your schema name)
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
</parent>
<groupId>com.amiya</groupId>
<artifactId>Spring-Boot-Demo-Project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Spring-Boot-Demo-Project</name>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.amiya.springbootdemoproject.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
// Annotations
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
// Class
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
}
Step 5: Inside the repository package
Create a simple interface and name the interface as DepartmentRepository. This
interface is going to extend the JpaRepository as we have discussed above.
Example
Java
package com.amiya.springbootdemoproject.repository;
import com.amiya.springbootdemoproject.entity.Department;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
// Annotation
@Repository
// Interface
public interface DepartmentRepository
package com.amiya.springbootdemoproject.service;
import com.amiya.springbootdemoproject.entity.Department;
import java.util.List;
// Interface
// Read operation
List<Department> fetchDepartmentList();
// Update operation
Long departmentId);
// Delete operation
Example 1-B
Java
package com.amiya.springbootdemoproject.service;
import com.amiya.springbootdemoproject.entity.Department;
import
com.amiya.springbootdemoproject.repository.DepartmentRepository;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
// Annotation
@Service
// Class
implements DepartmentService {
@Autowired
private DepartmentRepository departmentRepository;
// Save operation
@Override
return departmentRepository.save(department);
// Read operation
return (List<Department>)
departmentRepository.findAll();
// Update operation
@Override
public Department
updateDepartment(Department department,
Long departmentId)
Department depDB
= departmentRepository.findById(departmentId)
.get();
if (Objects.nonNull(department.getDepartmentName())
&& !"".equalsIgnoreCase(
department.getDepartmentName())) {
depDB.setDepartmentName(
department.getDepartmentName());
if (Objects.nonNull(
department.getDepartmentAddress())
&& !"".equalsIgnoreCase(
department.getDepartmentAddress())) {
depDB.setDepartmentAddress(
department.getDepartmentAddress());
if (Objects.nonNull(department.getDepartmentCode())
&& !"".equalsIgnoreCase(
department.getDepartmentCode())) {
depDB.setDepartmentCode(
department.getDepartmentCode());
return departmentRepository.save(depDB);
// Delete operation
@Override
departmentRepository.deleteById(departmentId);
}
}
package com.amiya.springbootdemoproject.controller;
import com.amiya.springbootdemoproject.entity.Department;
import com.amiya.springbootdemoproject.service.DepartmentService;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
// Annotation
@RestController
// Class
// Annotation
// Save operation
@PostMapping("/departments")
return departmentService.saveDepartment(department);
// Read operation
@GetMapping("/departments")
return departmentService.fetchDepartmentList();
// Update operation
@PutMapping("/departments/{id}")
public Department
return departmentService.updateDepartment(
department, departmentId);
// Delete operation
@DeleteMapping("/departments/{id}")
Long departmentId)
{
departmentService.deleteDepartmentById(
departmentId);
7. Create an xml for the bookstore. Validate the same using both DTD and XSD.
Create an xml for the bookstore. Validate the same using both DTD and XSD.
XML DTD
An XML document validated against a DTD is both "Well Formed" and "Valid".
What is a DTD?
A DTD defines the structure and the legal elements and attributes of an XML
document.
The DOCTYPE declaration above contains a reference to a DTD file. The content of
the DTD file is shown and explained below.
XML DTD
The purpose of a DTD is to define the structure and the legal elements and attributes
of an XML document:
Note.dtd:
<!DOCTYPE note
[
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
!DOCTYPE note - Defines that the root element of the document is note
!ELEMENT note - Defines that the note element must contain the elements:
"to, from, heading, body"
!ELEMENT to - Defines the to element to be of type "#PCDATA"
!ELEMENT from - Defines the from element to be of type "#PCDATA"
!ELEMENT heading - Defines the heading element to be of type "#PCDATA"
!ELEMENT body - Defines the body element to be of type "#PCDATA"
An XSD Example
This chapter will demonstrate how to write an XML Schema. You will also learn
that a schema can be written in different ways.
An XML Document
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
The XML document above consists of a root element, "shiporder", that contains a
required attribute called "orderid". The "shiporder" element contains three different
child elements: "orderperson", "shipto" and "item". The "item" element appears
twice, and it contains a "title", an optional "note" element, a "quantity", and a "price"
element.
We start by opening a new file that we will call "shiporder.xsd". To create the
schema we could simply follow the structure in the XML document and define each
element as we find it. We will start with the standard XML declaration followed by the
xs:schema element that defines a schema:
In the schema above we use the standard namespace (xs), and the URI associated
with this namespace is the Schema language definition, which has the standard
value of http://www.w3.org/2001/XMLSchema.
Next, we have to define the "shiporder" element. This element has an attribute and
it contains other elements, therefore we consider it as a complex type. The child
elements of the "shiporder" element is surrounded by a xs:sequence element that
defines an ordered sequence of sub elements:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Then we have to define the "orderperson" element as a simple type (because it does
not contain any attributes or other elements). The type (xs:string) is prefixed with
the namespace prefix associated with XML Schema that indicates a predefined
schema data type:
Next, we have to define two elements that are of the complex type: "shipto" and
"item". We start by defining the "shipto" element:
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
With schemas we can define the number of possible occurrences for an element with
the maxOccurs and minOccurs attributes. maxOccurs specifies the maximum number
of occurrences for an element and minOccurs specifies the minimum number of
occurrences for an element. The default value for both maxOccurs and minOccurs is
1!
Now we can define the "item" element. This element can appear multiple times
inside a "shiporder" element. This is specified by setting the maxOccurs attribute of
the "item" element to "unbounded" which means that there can be as many
occurrences of the "item" element as the author wishes. Notice that the "note"
element is optional. We have specified this by setting the minOccurs attribute to
zero:
We can now declare the attribute of the "shiporder" element. Since this is a required
attribute we specify use="required".
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
The previous design method is very simple, but can be difficult to read and maintain
when documents are complex.
The next design method is based on defining all elements and attributes first, and
then referring to them using the ref attribute.
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
</xs:schema>
The restriction element indicates that the datatype is derived from a W3C XML
Schema namespace datatype. So, the following fragment means that the value of
the element or attribute must be a string value:
<xs:restriction base="xs:string">
The restriction element is more often used to apply restrictions to elements. Look at
the following lines from the schema above:
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
8. Design a controller with servlet that provides the interaction with application developed
in experiment 1 and the database created in experiment.
We are going to create an application that consumes React for the user interface and Django for the
API of our application using Django REST framework (DRF).
Prerequisites
Basic knowledge of React, Python(Django) is required but I’ll try and boil things down as much as possible.
You can check out these articles to get started with React and Python:
Introduction to React
Django Tutorials
1. Install Python 3
2. Install Node.js
mkdir django-react-todoApp
cd django-react-todoApp
pipenv shell
Now that we have created our project, let’s go ahead and create an application called todo and migrate the
models into the database.
If everything works you should see the “Congratulations” page from Django.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
We’ll go ahead and set up our model for Todo item fields.
Modify todo/models.py as follows:
class Todo(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
completed = models.BooleanField(default=False)
def _str_(self):
return self.title
Completed: If the task is complete the status is True otherwise it remains False.
Django uses _str_() to display a default attribute to be displayed, in our case we return title to be shown from
our model.
Django comes with a built-in admin interface. The interface allows administrators and authorized users to
perform actions directly to the objects defined in the models.
We can add models to our Admin page using the admin.site.register() functions. In the todo app’s admin.py,
let’s add the model to our admin page.
class TodoAdmin(admin.ModelAdmin):
list = ('title', 'description', 'completed')
admin.site.register(Todo, TodoAdmin)
This will prompt you to enter the username, email, password, password(again). We can open the admin page
using the following link http://localhost:8000/admin.
We can now add and delete items from the admin page. Great!
Add rest_framework and corsheaders to the INSTALLED_APPS in backend/settings.py file and modifiy
the MIDDLEWARE:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
'corsheaders',
'rest_framework',
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'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',
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000',
Django-cors-headers is an HTTP-header-based that allows a server to indicate any other origins to your Django
application. Cross-origin Resource Sharing (CORS). Within the CORS_ORIGIN_WHITELIST , localhost:3000 will
serve as our port.
A serializer is a component that converts Django models to JSON objects and vice-versa.
touch todo/serializers.py
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
From the rest_framework package, we import the serializers. We create a class, TodoSerializer that extends
from the ModelSerializer class. We then go ahead and specify the model and fields we want to be returned.
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
Before creating webpages in Django we must define our URLs. A URL is an address to which a webpage is
served. Defining URLs describes what requests are returned from the views when the templates are rendered
in the browser.
router = routers.DefaultRouter()
router.register(r'todos', views.TodoView, 'todo')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls))
The next module is the router.urls that provides routing for our API.
create-react-app frontend
cd frontend
npm start
When we open our index.js file it should resemble the code below:
ReactDOM.render(
<App />,
document.getElementById('root')
);
reportWebVitals();
ReactDOM.render() renders a React element into the DOM in the given container element. It takes two
arguments. The first is the JSX being rendered, and the second displays the container element on the HTML
page.
const todoItems = [
id: 1,
},
id: 2,
title: "Visit",
completed: true
},
id: 3,
title: "Write",
completed: true
},
];
constructor(props) {
super(props);
this.state = {todoItems};
};
render() {
return (
<main className="content">
<div className="row">
{this.state.todoItems.map(item => (
<div>
<h1>{item.title}</h1>
<span>{item.description}</span>
</div>
))}
</ul>
</div>
</div>
</div>
</main>
We start by rendering a list of items. The list will be artificial data but later we’ll fetch the data from the API we
created in the previous steps.
We define a list of items. Each item has an id, title, description, and status of whether the task is completed or
not, completed.
We introduce the class constructor where we set the initial state. In our case, the internal state is the dummy
list of items, todoItems.
We use the built-in JavaScript map functionality in our JavaScript XML (JSX).
The map() method creates a new array populated with the results of calling a provided function on every
element in the calling array. We use curly braces to evaluate JavaScript expressions.
The render() method when called displays the JSX. The classname attribute in the render() method enables us
to use the CSS properties.
cd backend
We’ll need to modify the frontend/package.json by adding proxy. A proxy is used in the development
environment to facilitate communication between the server and the UI since the backend and the UI will be
running on different ports.
The proxy enables us to use Django’s localhost which handles our API requests.
[...]
"name": "frontend",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.6.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"web-vitals": "^0.2.4"
"reactstrap": "^8.8.1",
},
[...]
To consume our API instead of the artificial data, update the frontend/src/App.js with the snippet below:
constructor(props) {
super(props);
this.state = {
viewCompleted: false,
activeItem: {
title: "",
description: "",
completed: false
},
todoList: []
};
async componentDidMount() {
try {
this.setState({
todoList
});
} catch (e) {
console.log(e);
renderItems = () => {
);
<li
key={item.id}
>
<span
className={`todo-title mr-2 ${
}`}
title={item.description}
>
{item.title}
</span>
</li>
));
};
render() {
return (
<main className="content">
<div className="row">
{this.renderItems()}
</ul>
</div>
</div>
</div>
</main>
In our constructor, we created a few properties in our state object. We assigned the viewCompleted property
to false since our interface only shows items marked as not complete from our API at the moment.
The activeItem property includes the title, description and passes false to completed as the default status.
We then pass an empty array to our todoList because we are going to fetch our data from an API.
First, we wrap fetch() in a try/catch block to handle any network errors. We then call fetch() with
the await keyword, where we pass our API endpoints.
The async enables asynchronous operations, it returns a resolve value promise from our function.
We will define the componentDidMount() method as part of the async function. This enables us to perform
each fetch using the await keyword.
The componentDidMount() function is called by React when a component is rendered on the client-side. Read
more about life cycle functions from this article.
The setState() method in the componentDidMount() function is called when we want to update a change to
our previous state in the application.
We create a renderItems() function that uses the filter built-in array functionality, to show the completed
items from our todoList. The filter function takes a function to evaluate each item in the list.
We define a variable newItems to store the items which we display by using the map functionality. We use a
ternary conditional operator to show if an item description is marked as complete or not.
Ternary is a JavaScript operator that returns true in the first condition and false in the second part of an
expression.
In our render() method we display the items through the renderItems() function.
To handle actions such as adding tasks and marking them complete, we can create a modal component.
Modal enables us to create custom content such as popovers or dialog boxes in our applications.
Let’s go ahead and create a components folder in the src directory then create a file in it called Modal.js:
mkdir src/components
cd components
touch Modal.js
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label
} from "reactstrap";
constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem
};
handleChange = e => {
value = e.target.checked;
};
render() {
return (
<ModalBody>
<Form>
<FormGroup>
<Label for="title">Title</Label>
<Input
type="text"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup>
<Label for="description">Description</Label>
<Input
type="text"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup check>
<Label for="completed">
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
Save
</Button>
</ModalFooter>
</Modal>
);
In the code above we first import React and the components from reactstrap that we installed earlier. In the
constructor, we use the property that we created earlier in the App.js file. The props keyword passes the
argument to the activeItem component as objects.
The handleChange method takes note of a change in the state of a React component, takes the event as a
parameter, and does something to change the state.
We use destructuring assignment to create a checkbox where users can click to mark a task as complete. We
then change the activeItem in our state object by setState() method.
In our render() method we pass toggle and the onSave() method to props. We return the Modal component
when toggled.
We add the toggle component in the ModalHeader to enable dropping the modal. In the ModalBody, we add
the forms for adding the item title and item description.
In each FormGroup, we specify the activeItem value. We use the onChange event to detect when the input
value changes and returns the target input’s name and value.
Since the last FormGroup’s input type is a checkbox the target value will be checked as we assigned it in
our handlechange() method.
In the ModalFooter we will create a button to save our items using the onSave() method.
We can then create the add task and mark as completed functionalities in App.js.
Before we continue let’s install axios. It allows our applications to make a request to external endpoints. We
use it to perform CRUD operations to our API.
state = {
viewCompleted: false,
activeItem: {
title: "",
description: "",
completed: false
},
todoList: []
};
async componentDidMount() {
try {
this.setState({
todoList
});
} catch (e) {
console.log(e);
toggle = () => {
this.setState({ modal: !this.state.modal });
};
this.toggle();
if (item.id) {
axios
.put(`http://localhost:8000/api/todos/${item.id}/`, item)
return;
axios
.post("http://localhost:8000/api/todos/", item)
};
createItem = () => {
};
if (status) {
renderTabList = () => {
return (
<button
>
Complete
</button>
<button
>
Incomplete
</button>
</div>
);
};
renderItems = () => {
);
return newItems.map(item => (
<li
key={item.id}
>
<span
className={`todo-title mr-2 ${
}`}
title={item.description}
>
{item.title}
</span>
</li>
));
};
render() {
return (
<main className="content">
<div className="row">
<div className="">
<button onClick={this.createItem} className="btn btn-success">Add Task</button>
</div>
{this.renderTabList()}
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
): null}
</main>
First, import the Modal that we created earlier and axios. The toggle() method changes the Modal state when
toggled, if the expression is true it returns the properties defined in the Modal in Modal.js, otherwise nothing
happens. We add this in the render() method.
The handleSubmit() saves our items to the API, we use axios to make the requests to it. We use PUT to insert
the item into the already existing list of items according to the item id.
We then create a createItem() method to add our task which is defined in the render() method.
The displayCompleted() method checks the status of the viewCompleted we created in our state earlier and
returns true or false.
The renderTabList() method define two buttons Complete and Incomplete, if the viewCompleted() method
returns true, the item is Complete. If it returns false then the item is Incomplete. We had stated earlier how
the renderItems() method works.
Our render() method returns renderTabList(), renderItems() methods and the Add Task functionality which
uses the createItem() method to allow users to add task.
9.Create a custom server using http module and explore the other modules of Node JS like
OS, path, event.
To make HTTP requests in Node.js, there is a built-in module HTTP in Node.js to transfer
data over the HTTP. To use the HTTP server in the node, we need to require the HTTP
module. The HTTP module creates an HTTP server that listens to server ports and gives a
response back to the client.
Syntax:
const http = require('http');
Example 1: In this example, we can create an HTTP server with the help
of http.createServer() method.
Filename: max.js
javascript
// Create a server
response.write('Hello World!');
response.end();
Step to run this program: Run this max.js file using the below command:
node max.js
Output:
Console Output:
let options = {
host: 'www.geeksforgeeks.org',
path: '/courses',
method: 'GET'
};
// 'www.geeksforgeeks.org'
console.log(`STATUS: ${response.statusCode}`);
}).end();
Step to run this program: Run this max.js file using the below command:
node max.js
Similar Reads
1.What are the differences between HTTP module and Express.js module ?
3.Why are HTTP cookies used by Node.js for sending and receiving HTTP cookies?
4.Different types of module used for performing HTTP Request and Response in Node.js
Related Tutorials
1.Onsen UI
2.React Material UI
3.NuxtJS
4.D3.js
5.Spectre CSS
10. Develop an express web application that can interact with REST API to perform CRUD
operations on student data. (Use Postman)
API mean Application Programming Interface, which is a set of clearly defined methods
REST which stands for Representational State Transfer is an architectural style for
providing standards between computer systems on the web, making it easier for systems to
REST APIs mostly use JSON as the preferred choice for transferring data as they are easy to
In this tutorial, we will use Node, Express and MongoDB to create a REST API that would
1. GET — GET means to read the data. The function of this operation is to retrieve the data
from the database and present it to the user.
2. POST — POST, as the name suggests, is used to post/add new data to the database. It
allows users to add new data to the database.
3. PUT — PUT means to update the data already present in the database.
So, our REST API will perform all these four operations. We will use the Express package to
make our work easier. We will use MongoDB as the NoSQL database to store all our data.
So, we will do it step by step. First, we would build the API endpoints and then we would
connect to the database to perform actual operations. We would use Postman software for API
testing.
First of all, we need to download Node on our system. Then we can start creating our project.
So, first of all, we need to create a folder in our system where we would love to build our
npm init
It will ask various questions regarding the project, like name, description and other things. We
want to keep everything in the default mode except the name and description, which we can
After completion, we will see a package.json file in the folder. It contains all the data we just
gave to create this file. You can see the entry point is the index.js file.
After creating the package.json file, we need to download Express on our machine. To install
Express, we can:-
This will download and save express in our system and also will add express as a dependency
We will also like to download a development dependency named nodemon which will allow us
to develop faster. It will help us to avoid restarting the server each time we make a change and
Notice that we have used save-dev to install and add it in the package.json file as a dev
Now, we need to download MongoDB in our system and then create the cluster and connect it
Next, we must download mongoose to interact with the MongoDB database from our express
application.
Now, we are ready to start building our REST API. Before starting, I would like to show
"name": "rest-api",
"version": "1.0.0",
"description": "Test Rest API",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit
1"
},
"author": "Shubham",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.11.9"
},
"devDependencies": {
"nodemon": "^2.0.6"
}
}
So, let’s start building our REST API. First of all, we need to create a file named index.js; as we
We would start with the index.js file. We would start by requiring express into our system.
We will then set up our express app by writing the following line of code:-
So, then we would set up a GET function to test it using the browser. We pass a message as the
port number. We have used the OR operator there so that if there is any port number defined
via environment variables, it could use that; otherwise, it will use 4000. You can choose the
port number as per your choice. We will console.log a message to check if it is working
properly.
nodemon index
When we go to localhost:4000/api, we would see the message ‘It’s working!’. Also, in the
console, we would get the message we set for the console.
So, here we are, with the express server set up properly, and we sent our first GET request
successfully.
Now, we would like to have all four operations in a separate file called api.js under
the routes folder, as we want to avoid pushing everything into the index.js file.
So, we would remove the app.get part in this index.js file. We want to add the mongoose as a
Next, below the set-up of our express app, we would like to connect to MongoDB. We would do
mongoose.connect('mongodb://localhost/ourdata');
mongoose.Promise = global.Promise;
Here, ourdata is the name of the model we will be creating in MongoDb later in this tutorial.
We also updated the promises of the mongoose as the global promise since
Next, we would add a few more middlewares in the file. We would first add support to serve
static files. Though we won't be serving static files in this tutorial but having it is nice since we
app.use(express.static('public'));
We would then add the Express parser to parse the data sent or received from the database.
app.use(express.json());
We then set up the app to use the new api.js file we would create to hold all four operations.
app.use('/api',require('./routes/api'));
We have added ‘/api’ in the starting to avoid adding it to all four of the operations.
Finally, we added a middleware to handle the errors that occurred during the operations.
app.use(function(err,req,res,next){
res.status(422).send({error: err.message});
});
const express =
require('express')
;
const mongoose = require('mongoose');
// set up our express app
const app = express();
// connect to mongodb
mongoose.connect('mongodb://localhost/
ourdata');
mongoose.Promise = global.Promise;
app.use(express.static('public'));
app.use(express.json());
// initialize routes
app.use('/api',require('./routes/api'));
// error handling middleware
app.use(function(err,req,res,next){
//console.log(err);
res.status(422).send({error: err.message});
});
// listen for requests
app.listen(process.env.port || 4000, function()
{
console.log('Ready to Go!');
});
Next up, we create a folder named router and create a new file named api.js inside the folder.
This would hold all four CRUD operations we want to do with the REST API we are building.
We first start by requiring express in our file. Then we would create a router using the express
router.
So, let’s start building the four operations one by one. We would not be saving anything to the
database since we have not created one yet, but we would be testing them more simply.
So, we would start with the GET operator. We will write the code for the GET request in this
way:-
router.get('/students',function(req,res){
res.send({type: 'GET'});
};
Here, we are giving the endpoint and a function which gives a response which tells the type of
Next up is the PUT and DELETE request. For now, we would return the type of request for
both operations. It accepts the endpoint with an id which denotes the unique id which
Next, we would export the module to be used within the index.js file.
module.exports = router;
To test out these operations, we would use a software called Postman. It is amazing and helps
Here, we can choose the type of operation and the target URL for sending requests. For POST
requests, we need to send some JSON data while sending requests which we can be done by
You need to select Raw data type and then choose JSON as the format such as shown below:-
So, we can test all these operations via Postman very easily. We also need to provide the data
while PUT requests as we are updating the data. We only pass the data we need to update.
Next, we would create a folder named models and then create a student.js file within that
folder.
We would require mongoose in that folder and would build a Schema and then a model based
on that Schema. A Schema tells the model how the data is to be structured.
We are building a model which would contain data of the students — name, their roll number
1. Name — This is of String data type and is not a required field in the Schema.
2. Roll — This is also of String data type and is a required field. It cannot be left empty.
We then created the model named Student with the help of the StudentSchema that we
const mongoose =
require('mongoose');
const Schema = mongoose.Schema;
// create student schema & model
const StudentSchema = new Schema({
name: {
type: String,
},
roll: {
type: String,
required: [true, 'Roll field is required']
},
present: {
type: Boolean,
deafult: true
}
});
const Student =
mongoose.model('student',StudentSchema);
module.exports = Student;
Now, we would make all four API endpoints usable by saving and retrieving data from the
We then start with the GET request. We would get all the students in our database and send
them all as a response. You can add any sort of filtering for the students, but we are leaving the
find function empty to access every student from the database. We then use
the .catch(next) function to help catch any errors and pass it to the next middleware — error
router.get('/students',function(req,res,next){
Student.find({}).then(function(students){
res.send(students);
}).catch(next);
});
Next, we go for the POST request. We create a new student in the database and then return the
router.post('/students',function(req,res,next){
Student.create(req.body).then(function(student){
res.send(student);
}).catch(next);
});
Next, we have the PUT request. We would use the findOneAndUpdate function to find the
corresponding entry in the database using the id we passed in the URL endpoint. We then find
the same student with the help of their Id and return the updated student as a response.
router.put('/students/:id',function(req,res,next){
Student.findOneAndUpdate({_id:
req.params.id},req.body).then(function(student){
Student.findOne({_id: req.params.id}).then(function(student){
res.send(student);
});
});
});
Lastly, we have the DELETE request. We use the function findOneAndDelete to find the
corresponding student in the database via the id provided and delete that student from the
router.delete('/students/:id',function(req,res,next){
Student.findOneAndDelete({_id: req.params.id}).then(function(student){
res.send(student);
});
});
We can test all these using the Postman software very easily. Everything should work fine on
11. For the above application create authorized end points using JWT (JSON Web Token).
JSON Web Token is a open standard for transferring authorization details between client and
server. In JWT all the information is self contained, we don’t need to store them in server.
For Example: A user comes to our web application and login with username and password.
After verifying the credentials, sever provides the two JSON web tokens. One of them is an
Access Token and other is Refresh Token. After get the token server stores the token and pass
the access token in the authorization header. The server verify the token and identify the user.
Access token is valid for short time (depending on the configurations). In such a case if token
is invalid or expire, we will use the refresh token to generate the new access token.
Backend — Django
If you found any error to activate the virtual environment run the command before activate
After activate the virtual environment, we install the packages such as Django, Django REST
framework, Django REST framework simple JWT and Django CORS headers. The DRF
packages is used to create the API, while DRF simple JWT gives as ability to generate the JWT
Token and Django CORS headers is used to avoid CORS related issues.
# Python Packagespip install Django
pip install djangorestframework
pip install djangorestframework-simplejwt
pip install django-cors-headers
Once this is done, We will create the Project.
# Create the Project.django-admin startproject backend
Now, we have to change the project setting. Go into settings.py file and make the following
modifications:
from datetime import timedelta.....INSTALLED_APPS = [
...........
# Register your app
'corsheaders',
'rest_framework',
'rest_framework_simplejwt.token_blacklist'
].....CORS_ORIGIN_ALLOW_ALL = True.....MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...........
].....REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}.....SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=10),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True
}
Let’s look what we have done. First, we have register our app name (You will write your app
name), DRF, DRF simple JWT and CORS in INSTALLED_APPS. Second, we have set the
MIDDLEWARE to avoid the CORS related issue. Then, we have added the authentication JWT
Now, we are almost ready to test whether it is works or not. Before run the project we have to
apply the migration and create the user. Run this command to apply the migration:
# Apply the migration.python manage.py migration
Once this is done. we will create the user using this command:
# Create the user.python manage.py createsuperuser
Fill all the fields and now, we will start the development server using this command:
# Runserverpython manage.py runserver
After run the server, we will navigate to this http://localhost:8000/token/, we will see this
page which contains the form with username and password field.
Fill this form with your created username and password, you should see the access and refresh
token.
We all know, access token is invalid after some time. So by the use of refresh token we will
generate the new access token and refresh token as well. To generate the new access token
with the help of refresh token, we will navigate to this
URL http://localhost:8000/token/refresh/, we will see this page which contains the form with
Refresh field.
Fill this form with Refresh Token, you should see the new access and refresh token.
Now, we will create the views for testing. so, we will go in views.py file in our app directory and
Let’s look what we have done. First, we have import the modules and created the class based
view using simple APIView then, we have set the permission class for authenticated user.
Second, we have created the get method and set the response.
Now, we will create the URL for HomeView. To create the URL first, we have to create the
Second, we have to register the urls.py file path in our project directory urls.py file.
urlpatterns = [
......
path('', include('<app name>.urls')),
]
Now, we will use the POSTMAN to hit this URL http://localhost:8000/home/ with get
request and we get authentication credential not provided message because in our HomeView
we have set the permission class is IsAuthenticated means this page is only for authenticated
user.
So, we have to provide the access token in authorization to get the result. Now again, we will
create the get request with access token. To set the access token in POSTMAN, we have to click
on Authorization button and set the token type is Bearer Token and paste the access token.
Now, we have to add the logout functionality because we all know access token is valid for
some time.
By the use of refresh token, we will generate the new access token. But, what happens when
user wants to log out. The client can forgot both token. For example we have remove both the
access and refresh token from localStorage. But, if refresh token is stolen, then another client
use this token and use it. To prevent this, we will create the logout API, by using we can invalid
To create logout API, we will write the LogoutView in our views.py file in app directory:
class LogoutView(APIView): permission_classes = (IsAuthenticated,)
def post(self, request):
try: refresh_token =
request.data["refresh_token"] token =
RefreshToken(refresh_token) token.blacklist()
return Response(status=status.HTTP_205_RESET_CONTENT) except
Exception as e: return
Response(status=status.HTTP_400_BAD_REQUEST)
After create the LogoutView, we have to create the URL for LogoutView in our urls.py file in
app directory.
urlpatterns = [
.....
path('logout/', views.LogoutView.as_view(), name ='logout')
]
By using that URL http://localhost:8000/logout/, we can invalid the refresh token and add
token into blacklist. By using Postman we can hit this URL with POST request and pass the
Now all things is set on backend, We have tested all the API’s.
Frontend — React JS
There are many ways to connect the Django to your frontend but, In this tutorial we design the
frontend using React JS Framework. We have already created the API’s for authentication.
After setup the project run this command to run the react app:
# To run the react app.npm start
Then open http://localhost:3000/ to see your app.
After run the server successfully, we move further to design the application. So first, we will
After create the component folder in src we will create the login.js, logout.js, navigation.js and
home.js. Basically, we have created the different file for different use.
So first, we will write the code for navigation bar in navigations.js file.
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import React, { useState, useEffect} from 'react';export function
Navigation() { const [isAuth, setIsAuth] = useState(false);
useEffect(() => { if (localStorage.getItem('access_token') !==
null) { setIsAuth(true);
} }, [isAuth]); return (
<div>
<Navbar bg="dark" variant="dark">
<Navbar.Brand href="/">JWT Authentification</Navbar.Brand>
<Nav className="me-auto">
{isAuth ? <Nav.Link href="/">Home</Nav.Link> : null}
</Nav>
<Nav>
{isAuth ? <Nav.Link href="/logout">Logout</Nav.Link> :
<Nav.Link href="/login">Login</Nav.Link>}
</Nav>
</Navbar>
</div>
);
}
To deign the navigation page. First, we have imported all the packages and then define
Navigation function. Inside the navigation function, we have used the useState to store the
value in isAuth variable. Initially, we have set the value false. Then, used the useEffect and
check access token is present or not in localStoarge. if it is not present than change isAuth
Then, we have return the HTML code to design the navigation bar and used the ternary
operator condition which check isAuth is true or false. if it is then, it shows the Home and
Logout button on navigation bar otherwise it show login button like this:
After written navigation page code, we have to add route condition in our app.js file.
import './App.css';
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import {Login} from "./component/login";
import {Home} from "./component/Home";
import {Navigation} from './component/navigation';
import {Logout} from './component/logout';function App() { return
<BrowserRouter>
<Navigation></Navigation>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/login" element={<Login/>}/>
<Route path="/logout" element={<Logout/>}/>
</Routes>
</BrowserRouter>;
}
export default App;
In App.js file first, we have imported all the packages and files, then, written the route
condition for login, logout and home page.
After design the Navigation, we will write the code for login functionality in login.js file.
axios.post('http://localhost:8000/token/',
user ,{headers:
{'Content-Type': 'application/json'}},
withCredentials: true});
// Initialize the access & refresh token in localstorage.
localStorage.clear();
localStorage.setItem('access_token', data.access);
localStorage.setItem('refresh_token', data.refresh);
axios.defaults.headers.common['Authorization'] =
`Bearer ${data['access']}`;
window.location.href = '/' } return( <div className="Auth-
form-container">
<form className="Auth-form" onSubmit={submit}>
<div className="Auth-form-content">
<h3 className="Auth-form-title">Sign In</h3>
<div className="form-group mt-3">
<label>Username</label>
<input className="form-control mt-1"
placeholder="Enter Username"
name='username'
type='text' value={username}
required
onChange={e => setUsername(e.target.value)}/>
</div>
<div className="form-group mt-3">
<label>Password</label>
<input name='password'
type="password"
className="form-control mt-1"
placeholder="Enter password"
value={password}
required
onChange={e => setPassword(e.target.value)}/>
</div>
<div className="d-grid gap-2 mt-3">
<button type="submit"
className="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
)
}
Let’s look what we have done. First, we have initialize the react js packages. Second, we have
create the function which name is Login. Inside the login function we have created the submit
function. Inside the submit function we have written the axios post method to fetch the access
token and refresh token. After fetch the token, we have store this tokens in local storage and
navigate to the particular location which you want. For this case, I have route to my home
URL. Then, we have design the Login form with username and password fields. Whenever, we
click on submit button, the submit function is called and fetch the data from our backend login
API. If it is successful than we get the access token and navigate to other page or home page
After design the Login page, let’s move on to write the code for home page in our home.js file.
// Import the react JS packages
import {useEffect, useState} from "react";
import axios from "axios";
// Define the Login function.
export const Home = () => { const [message, setMessage] =
useState(''); useEffect(() =>
{ if(localStorage.getItem('access_token') === null){
window.location.href = '/login'
}
else{ (async () => { try { const
{data} = await axios.get(
'http://localhost:8000/home/', {
headers: {
'Content-Type': 'application/json'
}}
); setMessage(data.message);
} catch (e) { console.log('not auth')
} })()}; }, []); return <div
className="form-signin mt-5 text-center">
<h3>Hi {message}</h3>
</div>
}
Let’s look what we have done. First, we have initialize the react js packages. Second, we have
create the function which name is Home. Inside the Home we have used the useState to store
the message data and useEffect which called when every time the component renders. Inside
useEffect we have written if else condition to check the access token is present or not. If access
token is null in localStorage then, we will redirect to login page otherwise if we have token, we
will create the get request to fetch the data from home API and set the message. Then, We
have written the HTML code to display the message and our home page looks like:
We have design the home page also but, we all know that our access token is valid for very
short time. After short time when we refresh the page, we will get the 401 unauthorized error
because our access token is invalid. But we also know that in backend, we have created the
refresh token API, which will generate the new access token and refresh token.
But the problem is how we know or after how much time access token is invalid or not. To
resolve this problem, we use the interceptor in react js or in other words we can say
middleware.
Basically, Interceptors are methods which are triggered before or after the main method. So in
this case we have using the axios interceptor. There are two types of interceptors:
1. Request interceptor: — It allows you to write or execute your code before the request gets
sent.
2. Response interceptor: — It allows you to write or execute your code before response
reaches the calling end.
So in our case, we have using the response interceptor because, we have to check the response.
To write the response interceptor code first, we make the interceptor folder. Inside the
interceptor folder create the axiox.js file. Inside the axios.js file, we will write the code:
import axios from "axios";let refresh =
false;axios.interceptors.response.use(resp => resp, async error =>
{ if (error.response.status === 401 && !refresh) { refresh = true;
console.log(localStorage.getItem('refresh_token'))
const response = await
axios.post('http://localhost:8000/token/refresh/', {
refresh:localStorage.getItem('refresh_token')
}, { headers:
'Content-Type': 'application/json'
}
},{withCredentials: true}); if
(response.status === 200) {
axios.defaults.headers.common['Authorization'] = `Bearer
${response.data['access']}`;
localStorage.setItem('access_token', response.data.access);
localStorage.setItem('refresh_token', response.data.refresh);
return axios(error.config);
} }
refresh = false;return error;});
Let’s look what we have done. First, we have import the axios package and then, create the
axios response interceptor. Now, Every single time a request is made with the axios instance, if
When there is error occur first, we will check the error code. If the error code is 401, we need
to refresh the token. To refresh the token, we will create the POST request and get the new
access token and refresh token. After get the token, we will reinitialize the token in
After create the response interceptor. We have to the add the interceptor location in our
index.js file.
import './interceptors/axios';
Now, we will write the code for logout functionality in logout.js file.
import {useEffect, useState} from "react"
import axios from "axios";export const Logout = () => { useEffect(()
=> { (async () => { try {
const {data} = await
axios.post('http://localhost:8000/logout/',{
refresh_token:localStorage.getItem('refresh_token')
} ,{headers: {'Content-Type': 'application/json'}},
{withCredentials: true});
localStorage.clear();\
axios.defaults.headers.common['Authorization'] = null;
window.location.href = '/login'
} catch (e) {
console.log('logout not working', e)
}
})();
}, []); return (
<div></div>
)
}
To add the logout functionality, we have declares the packages and use the useEffect hooks.
Whenever we click on logout button, it call the backend logout API and remove all the tokens
12. Create a react application for the student management system having registration, login,
contact, about pages and implement routing to navigate through these pages.
Creating a registration form
The registration form is divided into two components in this tutorial i.e. Header and registrationForm,
which will be rendered in App.js.
Create a new folder named components inside the src folder. In the components folder following files
will be created:
header.js
registrationForm.js
style.css
Note: In react, JSX is used instead of HTML code. JSX is a markup language that contains HTML &
JavaScript.
In the header.js write the following code. You can copy-paste from here as well.
function App() {
return (
<div className="App">
<Header/>
</div>
);
}
If you have written the above code correctly the webpage will look like this:
header;
First Name
Last Name
Email id
Password
Confirm Password
Submit Button
Next, write the following code in the registrationForm.js to create the form body.
Note: Don’t forget to import style.css in registrationForm.js. In this tutorial, it has already been added.
body{
background: #bdc3c7; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2c3e50, #bdc3c7); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2c3e50, #bdc3c7); /* W3C, IE 10+/ Edge, Firefox 16+,
Chrome 26+, Opera 12+, Safari 7+ */
}
.form{
background-color: white;
border-radius: 5px;
width: 550px;
margin: 20px auto;
padding: 20px;
/* height: 600px; */
}
.form-body{
text-align: left;
padding: 20px 10px;
}
.form-body > *{
padding: 5px;
}
.form__label{
width: 40%;
}
.form_input{
width: 60%;
}
.footer{
text-align: center;
}
Add this component in App.js.
function App() {
return (
<div className="App">
<Header/>
<RegistrationForm/>
</div>
);
}
useState hook is used to maintain a state of a variable which you can update dynamically using
setState.
Now get to your form where you need to maintain the state of every input in the form. So that when
users hit submit button you can send the data to the backend API. In vanilla JavaScript it is done using
document.getElementById("demo").value while in react we will have a state for every input and
update it on every onChange event.
Import useState and setState hooks from react at top of our code. Now we can make a state for all
input elements.
We will add two attributes in the input tag to maintain the state variable i.e.
Value onChange
Value: The value attribute will contain the name of the fields, that we used while declaring states.
}
In this function, you get the id and the value entered inside the input box, as soon as you type anything
there, the state of that particular field will get updated. This is how you will maintain all the states so
that on submit button you can send all the required information to the backend APIs.
In this tutorial handleSubmit function is used in which you will get all the values that are filled in the
form. This function will be used to connect the app with the firebase. This is the final code for the
registration form which includes all the details you learned above in the tutorial so far.
return(
<div className="form">
<div className="form-body">
<div className="username">
<label className="form__label" for="firstName">First Name </label>
<input className="form__input" type="text" value={firstName} onChange = {(e) =>
handleInputChange(e)} id="firstName" placeholder="First Name"/>
</div>
<div className="lastname">
<label className="form__label" for="lastName">Last Name </label>
<input type="text" name="" id="lastName" value={lastName}
className="form__input" onChange = {(e) => handleInputChange(e)} placeholder="LastName"/>
</div>
<div className="email">
<label className="form__label" for="email">Email </label>
<input type="email" id="email" className="form__input" value={email} onChange =
{(e) => handleInputChange(e)} placeholder="Email"/>
</div>
<div className="password">
<label className="form__label" for="password">Password </label>
<input className="form__input" type="password" id="password" value={password}
onChange = {(e) => handleInputChange(e)} placeholder="Password"/>
</div>
<div className="confirm-password">
<label className="form__label" for="confirmPassword">Confirm Password </label>
<input className="form__input" type="password" id="confirmPassword"
value={confirmPassword} onChange = {(e) => handleInputChange(e)} placeholder="Confirm
Password"/>
</div>
</div>
<div class="footer">
<button onClick={()=>handleSubmit()} type="submit" class="btn">Register</button>
</div>
</div>
)
}
13. Create a service in react that fetches the weather information from open weather map.org and the
display the current and historical weather information using graphical representation using chart.js.
In your src folder, create a folder called components, and in that folder, create a file
called weather.js.
Now, let's call our weather component in our main app.js file.
import './App.css';
import React, { useEffect, useState } from "react";
import Weather from './components/weather';
export default function App() {
useEffect(() => {
const fetchData = async () => {
navigator.geolocation.getCurrentPosition(function(position) {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});
await fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=$
{long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
.then(res => res.json())
.then(result => {
setData(result)
console.log(result);
});
}
fetchData();
}, [lat,long])
return (
<div className="App">
{(typeof data.main != 'undefined') ? (
<Weather weatherData={data}/>
): (
<div></div>
)}
</div>
);
}
Importing Weather Component in app.js file
You can see that I've included a check in the return statement. If the type of data we are
getting is undefined, it will show us an empty div. And since the fetch data is an async
function, it's mandatory to include this check. It loads the function after all other functions are
done executing. So, if you remove this check, you will get an error.
This is because our application renders the return statement before the API call is made, and
there is nothing to show in that case so it throws an undefined error.
Here, we import a card from semantic-ui-react, and inside that card, a header that will show
the name of your city.
But the question is, how do we get data from our app.js to the weather.js component?
The answer is simple. We can use props in React to send data from a parent component to a
child component. In our case, our parent component is app.js and our child component is
weather.js.
You can see we get the name of the city according to the location.
You can add any other fields you want, like Humdity, Windspeed, Visibility, and more.
How to Format the Data and Add Today's Day and Date
Let's format the data so that it's easy to understand. We will add some more fields.
To start, add the unit of temperature. You can do this by adding °C after the
temperature.
Also, let's change sunrise and sunset to local time.
<p>Day: {moment().format('dddd')}</p>
<p>Date: {moment().format('LL')}</p>
Using moment.js
We import the moment package at the top and display today's day and date respectively. The
great thing about this package is that it automatically updates the date and the day.
This is how our weather.js look like now:
import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react';
import moment from 'moment';
First of all, let's make the card bigger, change the border-radius, add a cooler font and a
color, and remove the text alignment.
<div>
<p className="temp">Temprature: {weatherData.main.temp} °C</p>
</div>
</div>
)
@import url('https://fonts.googleapis.com/css2?family=Recursive&display=swap');
.main{
width: 700px;
border-radius: 15px;
background-color: #01579b;
}
.header{
background-color: #424242;
color: whitesmoke;
padding: 10px;
font-size: 28px;
border-radius: 15px;
font-family: 'Recursive', sans-serif;
}
.day{
padding: 15px;
color: whitesmoke;
font-family: 'Recursive', sans-serif;
font-size: 24px;
font-weight: 600;
}
.temp{
padding: 15px;
color: whitesmoke;
font-family: 'Recursive', sans-serif;
font-size: 18px;
}
styles.css
<div className="flex">
<p className="temp">Temprature: {weatherData.main.temp} °C</p>
<p className="temp">Humidity: {weatherData.main.humidity} %</p>
</div>
</div>
)
14. Create a TODO application in react with necessary components and deploy it into github.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
]
Copy
Then, save your changes.
Defining the Todo Model
Let’s create a model to define how the Todo items should be stored
in the database.
Open the todo/models.py file in your code editor and add the
following lines of code:
todo/models.py
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=120)
description = models.TextField()
completed = models.BooleanField(default=False)
def _str_(self):
return self.title
Copy
The code snippet above describes three properties on the Todo model:
title
description
completed
The completed property is the status of a task. A task will either
be completed or not completed at any time. Because you have created
a Todo model, you will need to create a migration file:
1. python manage.py makemigrations todo
2.
Copy
And apply the changes to the database:
1. python manage.py migrate todo
2.
Copy
You can test to see that CRUD operations work on the Todo model you
created by using the admin interface that Django provides by
default.
Open the todo/admin.py file with your code editor and add the
following lines of code:
todo/admin.py
from django.contrib import admin
from .models import Todo
class TodoAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'completed')
admin.site.register(Todo, TodoAdmin)
Copy
Then, save your changes.
You will need to create a “superuser” account to access the admin
interface. Run the following command in your terminal:
1. python manage.py createsuperuser
2.
Copy
You will be prompted to enter a username, email, and password for
the superuser. Be sure to enter details that you can remember
because you will need them to log in to the admin dashboard.
Start the server once again:
1. python manage.py runserver
2.
Copy
Navigate to http://localhost:8000/admin in your web browser. And log
in with the username and password that was created earlier:
You can create, edit, and, delete Todo items using this interface:
After experimenting with this interface, you can stop the server
(CONTROL+C or CTRL+C).
Step 2 — Setting Up the APIs
In this section, you will create an API using the Django REST
framework.
Install the djangorestframework and django-cors-headers using
Pipenv:
1. pipenv install djangorestframework django-cors-headers
2.
Copy
You need to add rest_framework and corsheaders to the list of
installed applications. Open the backend/settings.py file in your
code editor and update the INSTALLED_APPS and MIDDLEWARE sections:
backend/settings.py
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'todo',
]
MIDDLEWARE = [
'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',
'corsheaders.middleware.CorsMiddleware',
]
Copy
Then, add these lines of code to the bottom of
the backend/settings.py file:
backend/settings.py
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000'
]
Copy
django-cors-headers is a Python library that will prevent the errors
that you would normally get due to CORS rules. In
the CORS_ORIGIN_WHITELIST code, you
whitelisted localhost:3000 because you want the frontend (which will
be served on that port) of the application to interact with the API.
Creating serializers
You will need serializers to convert model instances to JSON so that
the frontend can work with the received data.
Create a todo/serializers.py file with your code editor. Open
the serializers.py file and update it with the following lines of
code:
todo/serializers.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title', 'description', 'completed')
Copy
This code specifies the model to work with and the fields to be
converted to JSON.
Creating the View
You will need to create a TodoView class in the todo/views.py file.
Open the todo/views.py file with your code editor and add the
following lines of code:
todo/views.py
from django.shortcuts import render
from rest_framework import viewsets
from .serializers import TodoSerializer
from .models import Todo
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
Copy
The viewsets base class provides the implementation for CRUD
operations by default. This code specifies the serializer_class and
the queryset.
Open the backend/urls.py file with your code editor and replace the
contents with the following lines of code:
backend/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from todo import views
router = routers.DefaultRouter()
router.register(r'todos', views.TodoView, 'todo')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
Copy
This code specifies the URL path for the API. This was the final
step that completes the building of the API.
You can now perform CRUD operations on the Todo model. The router
class allows you to make the following queries:
/todos/ - returns a list of all
the Todo items. CREATE and READ operations can be performed
here.
/todos/id - returns a single Todo item using the id primary
key. UPDATE and DELETE operations can be performed here.
Let’s restart the server:
1. python manage.py runserver
2.
Copy
Navigate to http://localhost:8000/api/todos in your web browser:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming
test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed == viewCompleted
);
To handle actions such as adding and editing tasks, you will need to
create a modal component.
First, create a components folder in the src directory:
1. mkdir src/components
2.
Copy
Then, create a Modal.js file and open it with your code editor. Add
the following lines of code:
frontend/src/components/Modal.js
import React, { Component } from "react";
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label,
} from "reactstrap";
render() {
const { toggle, onSave } = this.props;
return (
<Modal isOpen={true} toggle={toggle}>
<ModalHeader toggle={toggle}>Todo Item</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="todo-title">Title</Label>
<Input
type="text"
id="todo-title"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
placeholder="Enter Todo Title"
/>
</FormGroup>
<FormGroup>
<Label for="todo-description">Description</Label>
<Input
type="text"
id="todo-description"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
placeholder="Enter Todo description"
/>
</FormGroup>
<FormGroup check>
<Label check>
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button
color="success"
onClick={() => onSave(this.state.activeItem)}
>
Save
</Button>
</ModalFooter>
</Modal>
);
}
}
Copy
This code creates a CustomModal class and it nests the Modal
component that is derived from the reactstrap library.
This code also defined three fields in the form:
title
description
completed
These are the same fields that we defined as properties on the Todo
model in the backend.
The CustomModal receives activeItem, toggle, and onSave as props:
1. activeItem represents the Todo item to be edited.
2. toggle is a function used to control the Modal’s state (i.e.,
open or close the modal).
3. onSave is a function that is called to save the edited values
of the Todo item.
Next, you will import the CustomModal component into
the App.js file.
Revisit the src/App.js file with your code editor and replace the
entire contents with the following lines of code:
frontend/src/App.js
import React, { Component } from "react";
import Modal from "./components/Modal";
const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming
test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];
toggle = () => {
this.setState({ modal: !this.state.modal });
};
alert("save" + JSON.stringify(item));
};
createItem = () => {
const item = { title: "", description: "", completed: false };
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-
4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-
0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}
If you attempt to edit and save a Todo item, you will get an alert
displaying the Todo item’s object. Clicking on Save or Delete will
perform the respective actions on the Todo item.
Note:: Depending on your version of React and Reactstrap, you may
experience console errors. At the time of the revision, Warning:
Legacy context API has been detected within a strict-mode
tree. and Warning: findDOMNode is deprecated in
StrictMode. are known issues.
Now, you will modify the application so that it interacts with the
Django API you built in the previous section. Revisit the first
terminal window and ensure the server is running. If it is not
running, use the following command:
1. python manage.py runserver
2.
Copy
Note: If you closed this terminal window, remember that you will
need to navigate to the backend directory and use the virtual Pipenv
shell.
To make requests to the API endpoints on the backend server, you
will install a JavaScript library called axios.
In the second terminal window, ensure that you are in
the frontend directory and install axios:
1. npm install [email protected]
2.
Copy
Then open the frontend/package.json file in your code editor and add
a proxy:
frontend/package.json
[...]
"name": "frontend",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-scripts": "2.0.5",
"reactstrap": "^6.5.0"
},
[...]
The proxy will help in tunneling API requests
to http://localhost:8000 where the Django application will handle
them. Without this proxy, you would need to specify full paths:
axios.get("http://localhost:8000/api/todos/")
Copy
With proxy, you can provide relative paths:
axios.get("/api/todos/")
Copy
Note: You might need to restart the development server for the proxy
to register with the application.
Revisit the frontend/src/App.js file and open it with your code
editor. In this step, you will remove the hardcoded todoItems and
use data from requests to the backend
server. handleSubmit and handleDelete
Open the App.js file and replace it with this final version:
frontend/src/App.js
import React, { Component } from "react";
import Modal from "./components/Modal";
import axios from "axios";
componentDidMount() {
this.refreshList();
}
refreshList = () => {
axios
.get("/api/todos/")
.then((res) => this.setState({ todoList: res.data }))
.catch((err) => console.log(err));
};
toggle = () => {
this.setState({ modal: !this.state.modal });
};
if (item.id) {
axios
.put(`/api/todos/${item.id}/`, item)
.then((res) => this.refreshList());
return;
}
axios
.post("/api/todos/", item)
.then((res) => this.refreshList());
};
createItem = () => {
const item = { title: "", description: "", completed: false };
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
onClick={() => this.displayCompleted(true)}
className={this.state.viewCompleted ? "nav-link active" :
"nav-link"}
>
Complete
</span>
<span
onClick={() => this.displayCompleted(false)}
className={this.state.viewCompleted ? "nav-link" : "nav-
link active"}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-
4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-
0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}
export default App;
Copy
The refreshList() function is reusable that is called each time an
API request is completed. It updates the Todo list to display the
most recent list of added items.
The handleSubmit() function takes care of both the create and update
operations. If the item passed as the parameter doesn’t have an id,
then it has probably not been created, so the function creates it.
At this point, verify that your backend server is running in your
first terminal window:
1. python manage.py runserver
2.
Copy
Note: If you closed this terminal window, remember that you will
need to navigate to the backend directory and use the virtual Pipenv
shell.
And in your second terminal window, ensure that you are in
the frontend directory and start your frontend application:
1. npm start
2.
Copy
Now when you visit http://localhost:3000 with your web browser, your
application will allow you to READ, CREATE, UPDATE,
and DELETE tasks.