Online Shopping Cart
(E-commerce platform)
using Python and MySQL
Developing an Online Shopping Cart (E-commerce platform) using Python and MySQL involves several key components, including product browsing, cart management, payment integration, and admin management of products and orders.
Here's a step-by-step guide to help you
structure your project:
Step 1: Project Setup
- Choose
a Web Framework: You can use Flask or Django for
developing the web application. Django is more feature-rich but Flask is
simpler to start with.
- Install
Flask:
pip install flask
- Install
Django:
pip install django
- Set
up the MySQL Database:
- Install
MySQL and create the necessary database and tables using MySQL
Workbench or from the command line.
- Use
MySQL Connector to interact with MySQL from Python.
pip install mysql-connector-python
Step 2: Design the Database Schema
Here is a basic schema for your e-commerce platform:
- Products
Table:
CREATE TABLE products (
id INT PRIMARY KEY
AUTO_INCREMENT,
name VARCHAR(255) NOT
NULL,
description TEXT,
price DECIMAL(10, 2)
NOT NULL,
image_url VARCHAR(255),
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
- Users
Table:
CREATE TABLE users (
id INT PRIMARY KEY
AUTO_INCREMENT,
name VARCHAR(255),
email VARCHAR(255)
UNIQUE,
password VARCHAR(255),
role ENUM('admin',
'user') DEFAULT 'user',
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
- Cart
Table:
CREATE TABLE cart (
id INT PRIMARY KEY
AUTO_INCREMENT,
user_id INT,
product_id INT,
quantity INT DEFAULT
1,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY
(user_id) REFERENCES users(id),
FOREIGN KEY
(product_id) REFERENCES products(id)
);
- Orders
Table:
CREATE TABLE orders (
id INT PRIMARY KEY
AUTO_INCREMENT,
user_id INT,
total_amount DECIMAL(10,
2),
payment_status
ENUM('pending', 'completed') DEFAULT 'pending',
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY
(user_id) REFERENCES users(id)
);
- Order
Details Table (for keeping track of each product in the order):
CREATE TABLE order_details (
id INT PRIMARY KEY
AUTO_INCREMENT,
order_id INT,
product_id INT,
quantity INT,
price DECIMAL(10, 2),
FOREIGN KEY
(order_id) REFERENCES orders(id),
FOREIGN KEY
(product_id) REFERENCES products(id)
);
Step 3: Create the Backend Logic (Flask/Django)
- Connect
Flask/Django to MySQL:
import mysql.connector
db = mysql.connector.connect(
host="localhost",
user="root",
password="password",
database="ecommerce"
)
cursor = db.cursor()
- Routes/Views in Flask:
- Product
Browsing:
@app.route('/products')
def products():
cursor.execute("SELECT
* FROM products")
products =
cursor.fetchall()
return
render_template('products.html', products=products)
- Cart
Management:
@app.route('/cart')
def cart():
user_id = session['user_id']
cursor.execute("SELECT
* FROM cart WHERE user_id=%s", (user_id,))
cart_items =
cursor.fetchall()
return
render_template('cart.html', cart_items=cart_items)
- Add
to Cart:
@app.route('/add-to-cart/<int:product_id>')
def add_to_cart(product_id):
user_id = session['user_id']
cursor.execute("INSERT
INTO cart (user_id, product_id, quantity) VALUES (%s, %s, %s)", (user_id,
product_id, 1))
db.commit()
return redirect('/cart')
- Admin
Routes (Add/Edit/Delete Products):
@app.route('/admin/add-product', methods=['POST'])
def add_product():
name =
request.form['name']
description =
request.form['description']
price =
request.form['price']
cursor.execute("INSERT
INTO products (name, description, price) VALUES (%s, %s, %s)", (name,
description, price))
db.commit()
return redirect('/admin/products')
Step 4: Implement Payment Integration
- For
payment, you can integrate Stripe or PayPal.
- Stripe
Integration:
- Install
Stripe:
pip install stripe
- Example
route for payment:
import stripe
stripe.api_key = 'your_secret_key'
@app.route('/checkout', methods=['POST'])
def checkout():
total_amount =
request.form['total_amount']
intent =
stripe.PaymentIntent.create(
amount=int(total_amount)
* 100,
currency='usd',
)
return jsonify({'client_secret':
intent.client_secret})
Step 5: Admin Panel for Managing Products and Orders
- Create
admin views/routes where the admin can:
- View
all products.
- Add,
edit, and delete products.
- View
and manage orders (change order status).
- Add
a role check in the routes to ensure only users with the role of 'admin'
can access these routes.
Step 6: Frontend (HTML, CSS, Bootstrap)
- Design
the front end using HTML, CSS, and Bootstrap to
create a user-friendly interface.
- Templates:
- products.html:
Display all products.
- cart.html:
Display cart items.
- checkout.html:
Integrate the payment gateway.
Example snippet for products.html:
<div class="product">
{% for product in
products %}
<div class="card">
<img src="{{
product[4] }}" alt="{{ product[1] }}">
<h5>{{
product[1] }}</h5>
<p>{{
product[2] }}</p>
<p>${{
product[3] }}</p>
<a href="/add-to-cart/{{
product[0] }}" class="btn btn-primary">Add to Cart</a>
</div>
{% endfor %}
</div>
Step 7: Deploying the Application
- Local
Deployment:
- Run
the Flask/Django development server:
flask run # For Flask
python manage.py runserver
# For Django
- Production
Deployment:
- Use
Heroku, AWS, or DigitalOcean for production
deployment.
- Ensure
you configure the MySQL database connection in the production
environment.
Additional Features:
- User
Registration and Login: Implement a simple registration and login
system using Flask/Django authentication.
- Order
History: Allow users to view their past orders.
- Search
Products: Implement a product search feature using SQL LIKE queries.
To develop a detailed Online Shopping Cart (E-commerce
platform) using Python and MySQL, we’ll extend the basic
structure and give you a more comprehensive breakdown of the project
structure, including key components, files, and features for a
production-ready application.
We’ll use Flask for the web framework, but you can
follow similar principles for Django. The project will be structured in
a Model-View-Controller (MVC) format to keep the code clean and
organized.
Extended Project Structure
Here’s the folder structure of the project:
php
Copy code
ecommerce/
│
├── app/
│ ├──
__init__.py
│ ├──
models.py
│ ├──
routes.py
│ ├──
admin_routes.py
│ ├──
forms.py
│ ├── static/
│ │ ├── css/
│ │ └── images/
│ ├──
templates/
│ │ ├── base.html
│ │ ├── index.html
│ │ ├── product_detail.html
│ │ ├── cart.html
│ │ ├── checkout.html
│ │ ├── admin/
│ │ │ ├──
products.html
│ │ │ ├──
add_product.html
│ │ │
└── orders.html
│ ├──
utils.py
│ ├──
payment.py
│
├── migrations/ #
For database migrations (if using Flask-Migrate or Alembic)
│
├── config.py #
Configuration for database and secret keys
├── run.py #
Entry point to run the Flask app
├── requirements.txt #
Python dependencies
├── README.md #
Project documentation
1. run.py (Main Application Entry Point)
This is the file where the Flask app is initialized.
It imports the necessary components and starts the application.
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True)
2. app/__init__.py (Initialize Flask App)
This file sets up the app, database connection, and
blueprints (for different routes like user and admin routes).
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import Config
db = SQLAlchemy()
login_manager = LoginManager()
def create_app():
app =
Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
login_manager.init_app(app)
from .routes import
main as main_blueprint
from .admin_routes
import admin as admin_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(admin_blueprint, url_prefix="/admin")
return app
3. config.py (Configuration Settings)
This file contains configurations such as database
credentials, secret keys, and environment settings.
import os
class Config:
SECRET_KEY =
os.environ.get('SECRET_KEY') or 'your_secret_key'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'mysql://root:password@localhost/ecommerce'
SQLALCHEMY_TRACK_MODIFICATIONS = False
4. app/models.py (Database Models)
Here, you define the MySQL tables using SQLAlchemy
(or you can use the raw MySQL connector directly).
from . import db
from flask_login import UserMixin
class Product(db.Model):
id =
db.Column(db.Integer, primary_key=True)
name =
db.Column(db.String(255), nullable=False)
description =
db.Column(db.Text)
price =
db.Column(db.Numeric(10, 2), nullable=False)
image_url =
db.Column(db.String(255))
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
updated_at =
db.Column(db.DateTime, default=db.func.current_timestamp(),
onupdate=db.func.current_timestamp())
class User(UserMixin, db.Model):
id =
db.Column(db.Integer, primary_key=True)
name =
db.Column(db.String(255))
email =
db.Column(db.String(255), unique=True, nullable=False)
password =
db.Column(db.String(255), nullable=False)
role =
db.Column(db.String(50), default='user')
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class Cart(db.Model):
id =
db.Column(db.Integer, primary_key=True)
user_id =
db.Column(db.Integer, db.ForeignKey('user.id'))
product_id =
db.Column(db.Integer, db.ForeignKey('product.id'))
quantity =
db.Column(db.Integer, default=1)
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class Order(db.Model):
id =
db.Column(db.Integer, primary_key=True)
user_id =
db.Column(db.Integer, db.ForeignKey('user.id'))
total_amount =
db.Column(db.Numeric(10, 2))
payment_status =
db.Column(db.String(50), default='pending')
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class OrderDetails(db.Model):
id =
db.Column(db.Integer, primary_key=True)
order_id =
db.Column(db.Integer, db.ForeignKey('order.id'))
product_id =
db.Column(db.Integer, db.ForeignKey('product.id'))
quantity =
db.Column(db.Integer)
price =
db.Column(db.Numeric(10, 2))
5. app/routes.py (User Routes)
This file contains the routes for users, such as browsing
products, adding to the cart, viewing the cart, and checking out.
from flask import Blueprint, render_template, redirect,
url_for, session, request
from .models import Product, Cart, Order, OrderDetails
from . import db
main = Blueprint('main', __name__)
@main.route('/')
def index():
products =
Product.query.all()
return
render_template('index.html', products=products)
@main.route('/product/<int:id>')
def product_detail(id):
product =
Product.query.get_or_404(id)
return
render_template('product_detail.html', product=product)
@main.route('/cart')
def cart():
user_id = session['user_id']
cart_items =
Cart.query.filter_by(user_id=user_id).all()
return
render_template('cart.html', cart_items=cart_items)
@main.route('/add-to-cart/<int:product_id>')
def add_to_cart(product_id):
user_id = session['user_id']
cart_item =
Cart(user_id=user_id, product_id=product_id, quantity=1)
db.session.add(cart_item)
db.session.commit()
return
redirect(url_for('main.cart'))
@main.route('/checkout', methods=['GET', 'POST'])
def checkout():
if request.method
== 'POST':
user_id =
session['user_id']
# Process
payment, create order, and empty cart logic here
return
redirect(url_for('main.index'))
return
render_template('checkout.html')
6. app/admin_routes.py (Admin Routes)
This file contains routes for the admin, such as managing
products and viewing orders.
from flask import Blueprint, render_template, request,
redirect, url_for
from .models import Product, Order
from . import db
admin = Blueprint('admin', __name__)
@admin.route('/products')
def manage_products():
products =
Product.query.all()
return
render_template('admin/products.html', products=products)
@admin.route('/add-product', methods=['GET', 'POST'])
def add_product():
if request.method
== 'POST':
name =
request.form['name']
description =
request.form['description']
price =
request.form['price']
product =
Product(name=name, description=description, price=price)
db.session.add(product)
db.session.commit()
return
redirect(url_for('admin.manage_products'))
return
render_template('admin/add_product.html')
@admin.route('/orders')
def view_orders():
orders =
Order.query.all()
return
render_template('admin/orders.html', orders=orders)
7. app/forms.py (Forms)
This file contains forms for handling user inputs, such as
login, registration, and adding products.
from flask_wtf import FlaskForm
from wtforms import StringField, DecimalField, SubmitField
from wtforms.validators import DataRequired
class ProductForm(FlaskForm):
name =
StringField('Name', validators=[DataRequired()])
description =
StringField('Description')
price =
DecimalField('Price', validators=[DataRequired()])
submit =
SubmitField('Add Product')
8. app/utils.py (Helper Functions)
Helper functions can go here. For example, you can place
functions to handle the total amount calculation in the cart, send emails, or
other utilities.
9. app/static/ (Static Files)
This folder holds all static files such as CSS, images, and
JavaScript. You’ll use Bootstrap or your custom styles here to design
your frontend.
10. app/templates/ (HTML Templates)
Here you’ll create all the HTML templates for different
pages.
- base.html:
A base template containing header and footer.
- index.html:
Home page displaying all products.
- product_detail.html:
A detailed view of a single product.
- cart.html:
Displays the items in the user's cart.
- checkout.html:
Checkout page for placing an order.
- Admin
Templates:
- admin/products.html:
Displays the products list in the admin panel.
- admin/add_product.html:
Form to add a new product.
- admin/orders.html:
Displays the list of orders.
11. migrations/ (Database Migrations)
This folder contains database migration files if you are
using Flask-Migrate or Alembic for database version control.
12. requirements.txt (Dependencies)
This file lists all Python dependencies required for the
project.
Flask==2.1.0
Flask-SQLAlchemy==2.5.1
Flask-Login==0.5.0
Flask-WTF==0.15.1
MySQL-python==1.2.5
Features of this Extended Structure
- User
Authentication: Manage user login, registration, and session.
- Product
Management: Admin can add, edit, and delete products.
- Cart
Functionality: Users can add items to the cart and view/update the
cart.
- Order
Processing: Checkout and order management.
- Admin
Panel: Admin interface for managing products and viewing orders.
- Database
Management: SQLAlchemy to interact with the MySQL database.
1. run.py (Main Application Entry Point)
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True)
2. app/__init__.py (Initialize Flask App)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import Config
db = SQLAlchemy()
login_manager = LoginManager()
def create_app():
app =
Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
login_manager.init_app(app)
from .routes import
main as main_blueprint
from .admin_routes
import admin as admin_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(admin_blueprint, url_prefix="/admin")
return app
3. config.py (Configuration Settings)
import os
class Config:
SECRET_KEY =
os.environ.get('SECRET_KEY') or 'your_secret_key'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'mysql://root:password@localhost/ecommerce'
SQLALCHEMY_TRACK_MODIFICATIONS = False
4. app/models.py (Database Models)
from . import db
from flask_login import UserMixin
class Product(db.Model):
id =
db.Column(db.Integer, primary_key=True)
name =
db.Column(db.String(255), nullable=False)
description =
db.Column(db.Text)
price =
db.Column(db.Numeric(10, 2), nullable=False)
image_url =
db.Column(db.String(255))
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
updated_at =
db.Column(db.DateTime, default=db.func.current_timestamp(),
onupdate=db.func.current_timestamp())
class User(UserMixin, db.Model):
id =
db.Column(db.Integer, primary_key=True)
name =
db.Column(db.String(255))
email =
db.Column(db.String(255), unique=True, nullable=False)
password =
db.Column(db.String(255), nullable=False)
role =
db.Column(db.String(50), default='user')
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class Cart(db.Model):
id =
db.Column(db.Integer, primary_key=True)
user_id =
db.Column(db.Integer, db.ForeignKey('user.id'))
product_id =
db.Column(db.Integer, db.ForeignKey('product.id'))
quantity =
db.Column(db.Integer, default=1)
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class Order(db.Model):
id =
db.Column(db.Integer, primary_key=True)
user_id =
db.Column(db.Integer, db.ForeignKey('user.id'))
total_amount =
db.Column(db.Numeric(10, 2))
payment_status =
db.Column(db.String(50), default='pending')
created_at =
db.Column(db.DateTime, default=db.func.current_timestamp())
class OrderDetails(db.Model):
id =
db.Column(db.Integer, primary_key=True)
order_id =
db.Column(db.Integer, db.ForeignKey('order.id'))
product_id =
db.Column(db.Integer, db.ForeignKey('product.id'))
quantity =
db.Column(db.Integer)
price =
db.Column(db.Numeric(10, 2))
5. app/routes.py (User Routes)
from flask import Blueprint, render_template, redirect,
url_for, session, request
from .models import Product, Cart, Order, OrderDetails
from . import db
main = Blueprint('main', __name__)
@main.route('/')
def index():
products =
Product.query.all()
return
render_template('index.html', products=products)
@main.route('/product/<int:id>')
def product_detail(id):
product =
Product.query.get_or_404(id)
return
render_template('product_detail.html', product=product)
@main.route('/cart')
def cart():
user_id = session['user_id']
cart_items =
Cart.query.filter_by(user_id=user_id).all()
return
render_template('cart.html', cart_items=cart_items)
@main.route('/add-to-cart/<int:product_id>')
def add_to_cart(product_id):
user_id = session['user_id']
cart_item =
Cart(user_id=user_id, product_id=product_id, quantity=1)
db.session.add(cart_item)
db.session.commit()
return
redirect(url_for('main.cart'))
@main.route('/checkout', methods=['GET', 'POST'])
def checkout():
if request.method
== 'POST':
user_id =
session['user_id']
# Process
payment, create order, and empty cart logic here
return
redirect(url_for('main.index'))
return
render_template('checkout.html')
6. app/admin_routes.py (Admin Routes)
from flask import Blueprint, render_template, request,
redirect, url_for
from .models import Product, Order
from . import db
admin = Blueprint('admin', __name__)
@admin.route('/products')
def manage_products():
products =
Product.query.all()
return
render_template('admin/products.html', products=products)
@admin.route('/add-product', methods=['GET', 'POST'])
def add_product():
if request.method
== 'POST':
name =
request.form['name']
description =
request.form['description']
price =
request.form['price']
product =
Product(name=name, description=description, price=price)
db.session.add(product)
db.session.commit()
return
redirect(url_for('admin.manage_products'))
return
render_template('admin/add_product.html')
@admin.route('/orders')
def view_orders():
orders =
Order.query.all()
return
render_template('admin/orders.html', orders=orders)
7. app/forms.py (Forms)
from flask_wtf import FlaskForm
from wtforms import StringField, DecimalField, SubmitField
from wtforms.validators import DataRequired
class ProductForm(FlaskForm):
name =
StringField('Name', validators=[DataRequired()])
description =
StringField('Description')
price =
DecimalField('Price', validators=[DataRequired()])
submit =
SubmitField('Add Product')
8. app/utils.py (Helper Functions)
This file is where you can define helper functions. For
example, if you need to calculate the total price of the cart or handle utility
functions such as sending email notifications.
def calculate_cart_total(cart_items):
total = 0
for item in
cart_items:
total +=
item.quantity * item.product.price
return total
9. app/static/ (Static Files)
- CSS:
If you're using Bootstrap, include it here, along with any other
custom styles.
- Images:
Product images or other static resources will go here.
Example of a simple app/static/css/style.css:
body {
font-family:
Arial, sans-serif;
padding: 20px;
}
.navbar {
background-color: #333;
color: white;
}
10. app/templates/ (HTML Templates)
base.html (Base Template)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>{%
block title %}E-commerce{% endblock %}</title>
<link rel="stylesheet"
href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<nav class="navbar">
<a href="{{
url_for('main.index') }}">Home</a>
<a href="{{
url_for('main.cart') }}">Cart</a>
</nav>
<div class="content">
{% block
content %}{% endblock %}
</div>
</body>
</html>
index.html (Home Page)
{% extends 'base.html' %}
{% block title %}Products{% endblock %}
{% block content %}
<h1>Products</h1>
<ul>
{% for product in
products %}
<li>
<a href="{{
url_for('main.product_detail', id=product.id) }}">
<img
src="{{ product.image_url }}" alt="{{ product.name }}">
<h3>{{
product.name }}</h3>
<p>${{
product.price }}</p>
</a>
</li>
{% endfor %}
</ul>
{% endblock %}
product_detail.html
{% extends 'base.html' %}
{% block title %}{{ product.name }}{% endblock %}
{% block content %}
<h1>{{ product.name }}</h1>
<img src="{{ product.image_url }}" alt="{{
product.name }}">
<p>{{ product.description }}</p>
<p>Price: ${{ product.price }}</p>
<a href="{{ url_for('main.add_to_cart',
product_id=product.id) }}">Add to Cart</a>
{% endblock %}
cart.html
{% extends 'base.html' %}
{% block title %}Your Cart{% endblock %}
{% block content %}
<h1>Your Cart</h1>
<ul>
{% for item in
cart_items %}
<li>
<h3>{{
item.product.name }}</h3>
<p>Quantity:
{{ item.quantity }}</p>
<p>Price:
${{ item.product.price }}</p>
</li>
{% endfor %}
</ul>
<a href="{{ url_for('main.checkout') }}">Checkout</a>
{% endblock %}
checkout.html
{% extends 'base.html' %}
{% block title %}Checkout{% endblock %}
{% block content %}
<h1>Checkout</h1>
<form method="POST">
<button type="submit">Place
Order</button>
</form>
{% endblock %}
11. requirements.txt (Dependencies)
Flask==2.1.0
Flask-SQLAlchemy==2.5.1
Flask-Login==0.5.0
Flask-WTF==0.15.1
MySQL-python==1.2.5
Running the Project
- Install
dependencies:
pip install -r requirements.txt
- Set
up environment variables (SECRET_KEY, DATABASE_URL).
- Initialize
the database:
flask db init
flask db migrate
flask db upgrade
- Run
the Flask app:
python run.py
For Admin:
- Admins
can:
- Add
new products.
- Edit
or delete existing products.
- Manage
the product catalog.
The admin functionalities are handled in the routes such as:
@admin.route('/admin')
For Users:
- Users
can:
- View
products.
- Add
products to their cart.
- Checkout
and place orders.
These user functionalities are provided in routes like:
@main.route('/')
Important Distinction:
- The
user.role field in the user table defines whether a user is an admin
or a regular user. You can check the role within your routes to
restrict admin-specific actions using conditions like:
if current_user.role == 'admin':
# Admin specific
actions
This setup ensures that only admins can access the product
management features, while regular users interact with the shopping
functionality.