Python Flask
https://flask.palletsprojects.com/en/2.2.x/installation/
Create an environment
C:\flask_dev>py -3 -m venv venv
Activate the environment
C:\flask_dev>venv\Scripts\activate
Install Flask
venv C:\flask_dev>pip install Flask
C:\flask_dev\flaskreact\app.py
Install requirements
Flask-SQLAlchemy
Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application.
https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/
(venv) PS C:\flask_dev\flaskreact>pip install -U Flask-SQLAlchemy
C:\flask_dev\flaskreact\app.py
Flask + marshmallow for beautiful APIs
https://pypi.org/project/flask-marshmallow/
(venv) PS C:\flask_dev\flaskreact>pip install flask-marshmallow
Flask-Cors
A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible.
https://pypi.org/project/Flask-Cors/
(venv) PS C:\flask_dev\flaskreact>pip install -U flask-cors
C:\flask_dev\flaskreact\app.py
#C:\flask_dev\flaskreact\app.py from flask import Flask, jsonify from flask_cors import CORS #ModuleNotFoundError: No module named 'flask_cors' = pip install Flask-Cors from flask_marshmallow import Marshmallow #ModuleNotFoundError: No module named 'flask_marshmallow' = pip install flask-marshmallow https://pypi.org/project/flask-marshmallow/ from models import db, Countries app = Flask(__name__) CORS(app, supports_credentials=True) #app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdb.db' # Databse configuration mysql Username:password@hostname/databasename app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:''@localhost/flaskreact' db.init_app(app) with app.app_context(): db.create_all() ma=Marshmallow(app) class CountriesSchema(ma.Schema): class Meta: fields = ('ID','countryName') countries_schema = CountriesSchema(many=True) @app.route("/") def hello_world(): return "Hello, World!" @app.route('/listall',methods =['GET']) def listall(): all_countries = Countries.query.all() results = countries_schema.dump(all_countries) return jsonify(results)C:\flask_dev\flaskreact\models.py
#C:\flask_dev\flaskreact\models.py from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Countries(db.Model): __tablename__ = "countries" ID = db.Column(db.Integer, primary_key=True) countryName = db.Column(db.String(120), index=True, unique=True)run (venv) C:\flask_dev\flaskreact>flask run
http://127.0.0.1:5000/listall
React JS
https://create-react-app.dev/
Create Project
C:\react-js>npx create-react-app myreactdev
Run
C:\react-js\myreactdev> npm start
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js import React, { useState, useEffect } from 'react'; import Pagination from './Pagination' import axios from 'axios' import './App.css'; function App() { const [countries, setCountries] = useState([]) const [loading, setLoading] = useState(false) const [currentPage, setCurrentPage] = useState(1) const [CountriesPerPage] = useState(10) //10 Per Page useEffect(() => { const fetchPosts = async () => { setLoading(true) const res = await axios.get('http://127.0.0.1:5000/listall') setCountries(res.data) setLoading(false) } fetchPosts() }, []) if (loading && countries.length === 0) { return <h2>Loading...</h2> } //Get current countries const indexOfLastPost = currentPage * CountriesPerPage; const indexOfFirstPost = indexOfLastPost - CountriesPerPage; const CountriesList = countries.slice(indexOfFirstPost, indexOfLastPost) const howManyPages = Math.ceil(countries.length/CountriesPerPage) return ( <div className="container" style={{padding: 20}}> <h4 className="d-inline-block">ReactJS Python Flask Pagination</h4> <table className="table table-striped"> <thead className="thead-light "> <th>ID</th> <th>Country</th> </thead> <tbody> {CountriesList.map(row => <tr> <td>{row.ID}</td> <td>{row.countryName}</td> </tr>)} </tbody> </table> <Pagination pages = {howManyPages} setCurrentPage={setCurrentPage}/> </div> ); } export default App;Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react-js\myreactdev>npm i react-router-dom --save
Install Axios
https://www.npmjs.com/package/axios
C:\react-js\myreactdev>npm install axios --save
C:\react-js\myreactdev\src\Pagination.js
//C:\react-js\myreactdev\src\Pagination.js import React, { useState, useEffect } from 'react'; function Pagination({ pages = 7, setCurrentPage }) { //Set number of pages const numberOfPages = [] for (let i = 1; i <= pages; i++) { numberOfPages.push(i) } // Current active button number const [currentButton, setCurrentButton] = useState(1) // Array of buttons what we see on the page const [arrOfCurrButtons, setArrOfCurrButtons] = useState([]) useEffect(() => { let tempNumberOfPages = [...arrOfCurrButtons] let dotsInitial = '...' let dotsLeft = '... ' let dotsRight = ' ...' if (numberOfPages.length < 6) { tempNumberOfPages = numberOfPages } else if (currentButton >= 1 && currentButton <= 3) { tempNumberOfPages = [1, 2, 3, 4, dotsInitial, numberOfPages.length] } else if (currentButton === 4) { const sliced = numberOfPages.slice(0, 5) tempNumberOfPages = [...sliced, dotsInitial, numberOfPages.length] } else if (currentButton > 4 && currentButton < numberOfPages.length - 2) { const sliced1 = numberOfPages.slice(currentButton - 2, currentButton) const sliced2 = numberOfPages.slice(currentButton, currentButton + 1) tempNumberOfPages = ([1, dotsLeft, ...sliced1, ...sliced2, dotsRight, numberOfPages.length]) } else if (currentButton > numberOfPages.length - 3) { const sliced = numberOfPages.slice(numberOfPages.length - 4) tempNumberOfPages = ([1, dotsLeft, ...sliced]) } else if (currentButton === dotsInitial) { setCurrentButton(arrOfCurrButtons[arrOfCurrButtons.length-3] + 1) } else if (currentButton === dotsRight) { setCurrentButton(arrOfCurrButtons[3] + 2) } else if (currentButton === dotsLeft) { setCurrentButton(arrOfCurrButtons[3] - 2) } setArrOfCurrButtons(tempNumberOfPages) setCurrentPage(currentButton) }, [currentButton]) return ( <div className="pagination-container"> <a href="!#" className={`${currentButton === 1 ? 'disabled' : ''}`} onClick={() => setCurrentButton(prev => prev <= 1 ? prev : prev - 1)} > Prev </a> {arrOfCurrButtons.map(((item, index) => { return <a href="!#" key={index} className={`${currentButton === item ? 'active' : ''}`} onClick={() => setCurrentButton(item)} > {item} </a> }))} <a href="!#" className={`${currentButton === numberOfPages.length ? 'disabled' : ''}`} onClick={() => setCurrentButton(prev => prev >= numberOfPages.length ? prev : prev + 1)} > Next </a> </div> ); } export default Paginationreact-js\myreactdev\src\App.css
// body { margin: 0; background-color: #ffffff; } .pagination-container { display: flex; justify-content: center; align-items: center; width: 100%; font-weight: 500; font-size: 15px; } .pagination-container a { display: flex; justify-content: center; align-items: center; color: black; height: 40px; width: 40px; text-decoration: none; transition: background-color .2s; border: 1px solid #ddd; cursor: pointer; } .pagination-container a.active { background-color: #007bff; color: white; border: 1px solid #7cbddb; } .pagination-container a.disabled { opacity: 0.2; } .pagination-container a:hover:not(.active) {background-color: rgb(238, 238, 238);}react-js\myreactdev\public\index.html
//react-js\myreactdev\public\index.html <!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="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>Run C:\react-j\myreactdev>npm start
http://localhost:3000/