article

Tuesday, April 25, 2023

ReactJS Python Flask Click Load More Results | SQLAlchemy Mysql

ReactJS Python Flask Click Load More Results | SQLAlchemy Mysql

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/

Related Post