Online Shopping Cart (E-commerce platform) using Python and MySQL

Rashmi Mishra
0

 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

  1. 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

  1. 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:

  1. 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

);

  1. 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

);

  1. 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)

);

  1. 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)

);

  1. 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)

  1. Connect Flask/Django to MySQL:

import mysql.connector

db = mysql.connector.connect(

    host="localhost",

    user="root",

    password="password",

    database="ecommerce"

)

cursor = db.cursor()

  1. 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

  1. Create admin views/routes where the admin can:
    • View all products.
    • Add, edit, and delete products.
    • View and manage orders (change order status).
  2. 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)

  1. Design the front end using HTML, CSS, and Bootstrap to create a user-friendly interface.
  2. 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

  1. Local Deployment:
    • Run the Flask/Django development server:

flask run  # For Flask

python manage.py runserver  # For Django

  1. Production Deployment:
    • Use Heroku, AWS, or DigitalOcean for production deployment.
    • Ensure you configure the MySQL database connection in the production environment.

Additional Features:

  1. User Registration and Login: Implement a simple registration and login system using Flask/Django authentication.
  2. Order History: Allow users to view their past orders.
  3. 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

  1. Install dependencies:

pip install -r requirements.txt

  1. Set up environment variables (SECRET_KEY, DATABASE_URL).
  2. Initialize the database:

flask db init

flask db migrate

flask db upgrade

  1. 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.


Post a Comment

0Comments

Post a Comment (0)