https://python-guide-es.readthedocs.io/es/guide-es/dev/virtualenvs.html
Create an environment
ednalan@Cairocoders myapp % pip install virtualenv
ednalan@Cairocoders myapp % pip install virtualenv
Activate the environment
ednalan@Cairocoders myapp % source venv/bin/activate
(venv) ednalan@Cairocoders myapp %
Install Flask
https://pypi.org/project/Flask/
(venv) ednalan@Cairocoders myapp % pip install -U Flask
(venv) ednalan@Cairocoders myapp % flask run
Install requirements
pip install -U flask-cors
https://pypi.org/project/Flask-Cors/
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\myapp>pip install -U Flask-SQLAlchemy
python3 -m pip install
https://pypi.org/project/pymysql/
app.py
//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:root@localhost:8889/nextjsdb'
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=3):
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,
'price': rs.price
} for rs in products.items]
})
if __name__ == "__main__":
app.run(debug=True)
models.py
//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)
image = db.Column(db.String(150), index=True)
price = db.Column(db.Integer,default=0)
run (venv) C:\flask_dev\myapp>flask run Next.js
Install requirements
npm install axios
https://www.npmjs.com/package/axios
app\page.tsx
//app\page.tsx
import Link from "next/link";
import TableData from "@/components/tabledata";
import { Suspense } from "react";
import { Spinner } from "@/components/spinner";
export default function Home() {
return (
<div className="w-screen py-20 flex justify-center flex-col items-center bg-gray-300">
<div className="flex items-center justify-between gap-1 mb-5">
<h1 className="text-4xl font-bold">Next.js 14 Python Flask Mysql Pagination Next Prev | TailwindCSS DaisyUI</h1>
</div>
<Suspense fallback={<Spinner />}>
<TableData/>
</Suspense>
</div>
);
}
components\tabledata.tsx
//components\tabledata.tsx
"use client";
import React, { useEffect, useState } from "react";
import axios from 'axios' //npm install axios https://www.npmjs.com/package/axios
import Image from 'next/image'
export default function Users() {
const [products, setProducts] = useState([]);
const [info, setInfo] = useState({});
const url = "http://127.0.0.1:5000/products/1/3";
useEffect(() => {
fetchProducts(url);
}, []);
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);
};
return (
<div className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-3xl font-bold text-white mb-8">Introducing Our Latest Product</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{products.map((item, index) => (
<div key={index} className="bg-white rounded-lg shadow-lg p-8">
<div className="relative overflow-hidden">
<Image
src={`http://127.0.0.1:5000/static/images/${item.image}`}
width={400}
height={400}
alt="Photo"
/>
<div className="absolute inset-0 bg-black opacity-40" />
<div className="absolute inset-0 flex items-center justify-center">
<button className="bg-white text-gray-900 py-2 px-6 rounded-full font-bold hover:bg-gray-300">View Product</button>
</div>
</div>
<h3 className="text-xl font-bold text-gray-900 mt-4">{item.name}</h3>
<p className="text-gray-500 text-sm mt-2">Description: {item.name}</p>
<div className="flex items-center justify-between mt-4">
<span className="text-gray-900 font-bold text-lg">${item.price}.99</span>
<button className="bg-gray-900 text-white py-2 px-4 rounded-full font-bold hover:bg-gray-800">Add to Cart</button>
</div>
</div>
))}
</div>
<div className="w-1/2 items-center px-4 mt-6">
<div className="join grid grid-cols-2">
{info.prev_page_url ? (
<button className="join-item btn btn-primary btn-outline" onClick={handlePreviousPage}>
Previous
</button>
) : null}
{info.next_page_url ? (
<button className="join-item btn btn-primary btn-outline" onClick={handleNextPage}>
Next
</button>
) : null}
</div>
</div>
</div>
</div>
);
}
components\spinner.tsx
//components\spinner.tsx
export const Spinner = () => {
return (
<span className="loading loading-spinner loading-lg"></span>
);
};
run C:\nextjs>npm run dev https://github.com/cairocodes/Next.js-14-Python-Flask-Mysql-Pagination-Next-Prev-TailwindCSS-DaisyUI
