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