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/
