article

Wednesday, May 17, 2023

React js Python Flask Mysql Show Product List with pagination Next Prev

React js Python Flask Mysql Show Product List with pagination Next Prev

Python Flask 

https://flask.palletsprojects.com/en/2.3.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

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, request, jsonify
from flask_cors import CORS, cross_origin #ModuleNotFoundError: No module named 'flask_cors' = pip install Flask-Cors
  
from models import db, Products
  
app = Flask(__name__)
  
app.config['SECRET_KEY'] = 'cairocoders-ednalan'
#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'
  
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
  
CORS(app, supports_credentials=True)
  
db.init_app(app)
     
with app.app_context():
    db.create_all()
  
@app.route("/")
def hello_world():
    return "Hello, World!"
  
@app.route('/products/<int:page>/<int:per_page>', methods=['GET']) #http://127.0.0.1:5000/products/1/4
def products(page=1, per_page=4):
   
    nextpage = page + 1
    prevpage = page - 1
        
    total = Products.query.count()
    
    productdata = Products.query.order_by(Products.id.asc())  
    products = productdata.paginate(page=page, per_page=per_page)
    
    #print(products.next_num)
    #print(products.prev_num)
    
    nextnumber = products.next_num
    if nextnumber == None:
        next_page_url = ""
    else:
        next_page_url = f"http://127.0.0.1:5000/products/{nextpage}/{per_page}"
       
    prev_number = products.prev_num
    if prev_number == None:
        prev_page = ""
    else:
        prev_page = f"http://127.0.0.1:5000/products/{prevpage}/{per_page}"
        
    return jsonify({
        'total': total,
        'next_page_url': next_page_url,
        'prev_page_url': prev_page,
        'results': [{
            'id': rs.id,
            'name': rs.name,
            'image': rs.image,
            'description': rs.description
        } for rs in products.items]
    })
  
if __name__ == "__main__":
    app.run(debug=True)
C:\flask_dev\flaskreact\models.py
 
#C:\flask_dev\flaskreact\models.py
from flask_sqlalchemy import SQLAlchemy
      
db = SQLAlchemy()
      
class Products(db.Model):
    __tablename__ = "products"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(150), index=True, unique=True)
    image = db.Column(db.String(150), index=True, unique=True)
    description = db.Column(db.String(255), index=True, unique=True)
run (venv) C:\flask_dev\flaskreact>flask run
http://127.0.0.1:5000/products/1/4

Database Table

CREATE TABLE `products` (
`id` bigint(20) UNSIGNED NOT NULL,
`name` varchar(255) NOT NULL,
`image` varchar(255) NOT NULL,
`description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `products` (`id`, `name`, `image`, `description`) VALUES
(1, 'Asus Vivobook 14', '1.jpg', 'Asus Vivobook 14\" AMD Ryzen 3 3250 8gb/128gb M415DA-R3128 Slate [Grey]'),
(2, 'Acer Aspire 5 15.6', '2.jpg', 'Acer Aspire 5 15.6” laptop Ryzen 5-5500U 8GB RAM 512GB SSD - Silver'),
(3, 'Lenovo laptop t440', '3.jpg', 'Lenovo laptop t440 t450 t460 t470s i5 i7 5th gen 7th gen laptop built in camera for online class'),
(4, 'HP 3.0 2TB Flash Drive Metal', '4.jpg', 'HP 3.0 2TB Flash Drive Metal Waterproof High speed U Disk Flash Drive '),
(5, 'Desk Mat Laptop Mat Pad Gaming', '5.jpg', 'Desk Mat Laptop Mat Pad Gaming Large Mouse Pad Long Mousepad Leatherette Waterproof'),
(6, 'XIAOMI Original OTG metal pendrive 2TB', '6.jpg', 'XIAOMI Original OTG metal pendrive 2TB'),
(7, 'Monsy D103 Laptop Stand Aluminum Alloy', '7.jpg', 'Monsy D103 Laptop Stand Aluminum Alloy'),
(8, 'HD Webcam Web Camera', '8.jpg', 'HD Webcam Web Camera'),
(9, '300Mbps Wireless-N WiFi Repeater ', '9.jpg', '300Mbps Wireless-N WiFi Repeater '),
(10, 'Mumu 6033 Unisex 15.6 Inch Laptop', '10.jpg', 'Mumu 6033 Unisex 15.6 Inch Laptop Usb Backpack Anti Theft Men Bag Travel Male Leisure Bags'),
(11, 'Mini Computer Speakers Stereo USB Wired Powered for PC/Laptops/Smartphone', '11.jpg', 'Mini Computer Speakers Stereo USB Wired Powered for PC/Laptops/Smartphone');

React JS
https://create-react-app.dev/

Create Project
C:\react-js>npx create-react-app myreactdev

Run
C:\react-js\myreactdev> npm start

https://github.com/axios/axios

Installing the Axios Client
$ npm install axios

C:\reactdev\myreactdev>npm install axios
C:\react-js\myreactdev\src\App.js

//C:\react-js\myreactdev\src\App.js
import React, { useEffect, useState } from "react";
import axios from "axios";
// Component
import Navbar from "./Component/Navbar";
import ProductList from "./Component/ProductList";
 
function App() {
  const [products, setProducts] = useState([]);
  const [info, setInfo] = useState({});
  
  const url = "http://127.0.0.1:5000/products/1/4";
 
  const fetchProducts = (url) => {
    axios
      .get(url)
      .then((data) => {
        setProducts(data.data.results);
        //console.log(data.data.results);
        setInfo(data.data);
        //console.log(data.data);
      })
      .catch((error) => {
        console.log(error);
      });
  };
   
  const handleNextPage = () => {
    fetchProducts(info.next_page_url);
    window.scrollTo(0, 0);
  };
  
  const handlePreviousPage = () => {
    fetchProducts(info.prev_page_url);
    window.scrollTo(0, 0);
  };
  
  useEffect(() => {
    fetchProducts(url);
  }, []);
 
 
  return (
    <>
      <Navbar brand="Cairocoders" />
 
      <div className="container py-5"><p><h2>React js Python Flask Mysql Show Product List with pagination Next Prev</h2></p>
        <nav>
  
          <ul className="pagination justify-content-center">
            {info.prev_page_url ? (
              <li className="page-item">
                <button className="page-link" onClick={handlePreviousPage}>
                  Previous
                </button>
              </li>
            ) : null}
            {info.next_page_url ? (
              <li className="page-item">
                <button className="page-link" onClick={handleNextPage}>
                  Next
                </button>
              </li>
            ) : null}
          </ul>
  
        </nav>
      </div>
       
      <ProductList products={products} />
       
      <div className="container pb-5">
        <nav>
          <ul className="pagination justify-content-center">
            {info.prev_page_url ? (
              <li className="page-item">
                <button className="page-link" onClick={handlePreviousPage}>
                  Previous
                </button>
              </li>
            ) : null}
            {info.next_page_url ? (
              <li className="page-item">
                <button className="page-link" onClick={handleNextPage}>
                  Next
                </button>
              </li>
            ) : null}
          </ul>
        </nav>
      </div>
	  
    </>
  );
}
 
export default App;
C:\react-js\myreactdev\src\Component\Navbar.js
//C:\react-js\myreactdev\src\Component\Navbar.js
import React from "react";
 
const Navbar = ({ brand }) => {
  return (
    <nav className="navbar navbar-dark bg-dark">
      <div className="container">
        <a className="navbar-brand text-uppercase" href="/">
          {brand}
        </a>
      </div>
    </nav>
  );
};
 
export default Navbar;
C:\react-js\myreactdev\src\Component\ProductList.js
//C:\react-js\myreactdev\src\Component\ProductList.js
import React from "react";
 
const ProductList = ({ products }) => {
  return (
    <div className="container">
      <div className="row">
        {products.map((item, index) => (
          <div key={index} className="col-lg-3 col-md-6 col-sm-12 mb-4">
            <div className="card" style={{ minWidth: "200px" }}>
                <img src={`http://127.0.0.1:5000/static/${item.image}`} alt="Product list" className="card-img-top" />
              <div className="card-body">
                <h5 className="card-title">{item.name}</h5>
                <hr />
                <p className="card-text">Description: {item.description}</p>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};
 
export default ProductList;
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/

Related Post