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
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, User 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('/users/<int:page>/<int:per_page>', methods=['GET']) def posts(page=1, per_page=10): total = User.query.count() print(total) posts = User.query.order_by(User.id.asc()) posts = posts.paginate(page=page, per_page=per_page) return jsonify({ 'total': total, 'page': page, 'per_page': per_page, 'has_next': posts.has_next, 'has_prev': posts.has_prev, 'page_list': [iter_page if iter_page else '...' for iter_page in posts.iter_pages()], 'data': [{ 'id': p.id, 'fullname': p.name, 'email': p.email, 'password': p.password, 'photo': p.photo } for p in posts.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 from uuid import uuid4 db = SQLAlchemy() def get_uuid(): return uuid4().hex class User(db.Model): __tablename__ = "users" id = db.Column(db.String(11), primary_key=True, unique=True, default=get_uuid) name = db.Column(db.String(150), unique=True) email = db.Column(db.String(150), unique=True) password = db.Column(db.Text, nullable=False) photo = db.Column(db.String(150), unique=True)run (venv) C:\flask_dev\flaskreact>flask run
http://127.0.0.1:5000/users/1/4
users.sql : https://github.com/cairocodes/cairocoders/blob/main/users.sql
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, { useEffect, useState } from 'react'; import "./App.css"; function App() { const perPage = 4; const [totalPages, setTotalPages] = useState(1); const [page, setPage] = useState(1); const [userList, setUserList] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { const getUserList = () => { setLoading(true); fetch(`http://127.0.0.1:5000/users/${page}/${perPage}`) .then(res => res.json()) .then(res => { setTotalPages(res.total); setUserList([...userList, ...res.data]); setLoading(false); }); } getUserList(); }, [page]); return ( <div className="container"> <div className="row justify-content-center"> <div className="col-12 col-sm-8 col-lg-6"> <div className="section_heading text-center wow fadeInUp"> <h3>ReactJS Python Flask Click Load More Results | SQLAlchemy Mysql</h3> <div className="line"></div> </div> </div> </div> <div className="row" style={{padding: 20}}> {userList.map((x, i) => { return <div key={i} className="col-12 col-sm-6 col-lg-3"> <div className="single_advisor_profile wow fadeInUp"> <div className="advisor_thumb"> <img alt="pic" src={x.photo} width="315" height="315"/></div> <div className="single_advisor_details_info"> <h6>{x.fullname}</h6> <p className="designation">{x.email}</p> </div> </div> </div> })} <div className="clearfix"></div> {totalPages !== page && <button className="btn btn-primary" onClick={() => setPage(page + 1)}>{loading ? 'Loading...' : 'Load More'}</button>} </div> </div> ); } export default App;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>react-js\myreactdev\src\App.css
//react-js\myreactdev\src\App.css body{margin-top:20px; background:#eee; } .single_advisor_profile { position: relative; margin-bottom: 50px; -webkit-transition-duration: 500ms; transition-duration: 500ms; z-index: 1; border-radius: 15px; -webkit-box-shadow: 0 0.25rem 1rem 0 rgba(47, 91, 234, 0.125); box-shadow: 0 0.25rem 1rem 0 rgba(47, 91, 234, 0.125); } .single_advisor_profile .advisor_thumb { position: relative; z-index: 1; border-radius: 15px 15px 0 0; margin: 0 auto; padding: 30px 30px 0 30px; background-color: #3f43fd; overflow: hidden; } .single_advisor_profile .advisor_thumb::after { -webkit-transition-duration: 500ms; transition-duration: 500ms; position: absolute; width: 150%; height: 80px; bottom: -45px; left: -25%; content: ""; background-color: #ffffff; -webkit-transform: rotate(-15deg); transform: rotate(-15deg); } @media only screen and (max-width: 575px) { .single_advisor_profile .advisor_thumb::after { height: 160px; bottom: -90px; } } .single_advisor_profile .single_advisor_details_info { position: relative; z-index: 1; padding: 30px; text-align: right; -webkit-transition-duration: 500ms; transition-duration: 500ms; border-radius: 0 0 15px 15px; background-color: #ffffff; } .single_advisor_profile .single_advisor_details_info::after { -webkit-transition-duration: 500ms; transition-duration: 500ms; position: absolute; z-index: 1; width: 50px; height: 3px; background-color: #3f43fd; content: ""; top: 12px; right: 30px; } .single_advisor_profile .single_advisor_details_info h6 { margin-bottom: 0.25rem; -webkit-transition-duration: 500ms; transition-duration: 500ms; } @media only screen and (min-width: 768px) and (max-width: 991px) { .single_advisor_profile .single_advisor_details_info h6 { font-size: 14px; } } .single_advisor_profile .single_advisor_details_info p { -webkit-transition-duration: 500ms; transition-duration: 500ms; margin-bottom: 0; font-size: 14px; } @media only screen and (min-width: 768px) and (max-width: 991px) { .single_advisor_profile .single_advisor_details_info p { font-size: 12px; } } .single_advisor_profile:hover .advisor_thumb::after, .single_advisor_profile:focus .advisor_thumb::after { background-color: #070a57; } .single_advisor_profile:hover .single_advisor_details_info, .single_advisor_profile:focus .single_advisor_details_info { background-color: #070a57; } .single_advisor_profile:hover .single_advisor_details_info::after, .single_advisor_profile:focus .single_advisor_details_info::after { background-color: #ffffff; } .single_advisor_profile:hover .single_advisor_details_info h6, .single_advisor_profile:focus .single_advisor_details_info h6 { color: #ffffff; } .single_advisor_profile:hover .single_advisor_details_info p, .single_advisor_profile:focus .single_advisor_details_info p { color: #ffffff; }Run C:\react-j\myreactdev>npm start
http://localhost:3000/