Sunteți pe pagina 1din 14

Lab Building Simple Shopping Cart using Python, Flask,

MySQL

Introduction
We will see here how to build a simple shopping cart using Python, Flask, MySQL. This
shopping cart is very simple and it does not have checkout option, payment option. This is
about to display products in an online shopping portal, add item to cart, remove item from
cart and remove all items from cart at once or empty cart.

Lab Objective
After completing this lab, you will be able to:

 Create Project Directory


 Create MySQL Table
 Dump Data
 Configure Flask
 Configure a Database and URL
 Create Template File
 Test the Application

Prerequisites
 Python 3.7.4, MySQL 8.0.17, Flask 1.1.1, Windows 10
 Need flask_table and MySQL modules : check tutorial for installation these two
modules

Lab Procedure
A. Creating Project Directory
First step is to create a project root directory under which we will put all our required
files for the project.
Let’s say we are going to create a project root directory “shopcart”. We may not
mention the project root directory in subsequent sections and we will assume that we
are talking with respect to the project’s root directory.

B. Creating MySQL Table


Create a table product under database roytuts in MySQL server with the following
structure:
CREATE TABLE `product` (

`id` int unsigned NOT NULL AUTO_INCREMENT,


`name` varchar(255) NOT NULL,

`code` varchar(255) NOT NULL,

`image` text NOT NULL,

`price` double NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4;

C. Dumping Data
We will test our application when we finish with coding, so dump some data
into product table.
INSERT INTO `product` (`id`, `name`, `code`, `image`, `price`) VALUES

(1, 'American Tourist', 'AMTR01', 'product-images/bag.jpg',


12000.00),

(2, 'EXP Portable Hard Drive', 'USB02', 'product-images/external-


hard-drive.jpg', 5000.00),

(3, 'Shoes', 'SH03', 'product-images/shoes.jpg', 1000.00),

(4, 'XP 1155 Intel Core Laptop', 'LPN4', 'product-images/laptop.jpg',


80000.00),

(5, 'FinePix Pro2 3D Camera', '3DCAM01', 'product-images/camera.jpg',


150000.00),

(6, 'Simple Mobile', 'MB06', 'product-images/mobile.jpg', 3000.00),

(7, 'Luxury Ultra thin Wrist Watch', 'WristWear03', 'product-


images/watch.jpg', 3000.00),

(8, 'Headphone', 'HD08', 'product-images/headphone.jpg', 400.00);

D. Configuring Flask
Create the below app.py script(py is the extension to indicate Python script) where we
import the flask module. This file should be created under the project root directory.
Notice how we create flask instance. We have configured a secret key, which is
required for your application’s session.
from flask import Flask

app = Flask(__name__)
app.secret_key = "secret key"

E. Database Configuration
We create the below db_config.py Python script under project root directory to setup
the MySQL database configurations for connecting to database.
We need to configure database connection with flask module and that’s why we have
imported app module and setup the MySQL configuration with flask module.
from app import app

from flaskext.mysql import MySQL

mysql = MySQL()

# MySQL configurations

app.config['MYSQL_DATABASE_USER'] = 'root'

app.config['MYSQL_DATABASE_PASSWORD'] = 'root'

app.config['MYSQL_DATABASE_DB'] = 'roytuts'

app.config['MYSQL_DATABASE_HOST'] = 'localhost'

mysql.init_app(app)

F. Configuring URLs
Next we will create main.py script that will define all URIs or Action paths for
performing certain operations used for cart or to fetch all products from the database.
It will connect to MySQL database server and query the database to read all products
from the database table.
In this script we perform certain operations with user interaction.
We first import required modules into the script. We then define the end-point / for
displaying a view where user will see all the products.
Next we need to validate user input data and save those input data into into cart, i.e.,
flask session. So we define another end-point /add. Here we fetch the data based on
product’s code from MySQL database and put into session against unique product
keys.
We use http method GET for displaying view and POST method for sending data to
server side. By default http method is GET if you do not specify http method.
We use render_template function from flask to show the view.
Initially when there is no product or item in the cart then you won’t see any item or
product in the cart on home page or products page.
If you add product to cart from Add to Cart link shown on each product then you will
see product gets added and displayed into the cart.
We define /empty endpoint to clear all items from the cart.
Next we define /delete/<string:code> end-point where user deletes product one
by one from the cart.

import pymysql

from app import app

from db_config import mysql

from flask import flash, session, render_template, request, redirect,


url_for

from werkzeug import generate_password_hash, check_password_hash

@app.route('/add', methods=['POST'])

def add_product_to_cart():

cursor = None

try:

_quantity = int(request.form['quantity'])

_code = request.form['code']

# validate the received values

if _quantity and _code and request.method == 'POST':

conn = mysql.connect()

cursor = conn.cursor(pymysql.cursors.DictCursor)

cursor.execute("SELECT * FROM product WHERE code=


%s", _code)

row = cursor.fetchone()

itemArray = { row['code'] : {'name' : row['name'], 'code' :


row['code'], 'quantity' : _quantity, 'price' : row['price'],
'image' : row['image'], 'total_price': _quantity * row['price']}}
all_total_price = 0

all_total_quantity = 0

session.modified = True

if 'cart_item' in session:

if row['code'] in session['cart_item']:

for key, value in


session['cart_item'].items():

if row['code'] == key:

#session.modified = True

#if session['cart_item'][key]['quantity'] is not None:

#session['cart_item'][key]['quantity'] = 0

old_quantity = session['cart_item'][key]['quantity']

total_quantity = old_quantity + _quantity

session['cart_item'][key]['quantity'] = total_quantity

session['cart_item'][key]['total_price'] = total_quantity *
row['price']

else:

session['cart_item'] = array_merge(session['cart_item'], itemArray)

for key, value in session['cart_item'].items():

individual_quantity = int(session['cart_item'][key]['quantity'])

individual_price = float(session['cart_item'][key]['total_price'])

all_total_quantity = all_total_quantity + individual_quantity

all_total_price = all_total_price + individual_price

else:
session['cart_item'] = itemArray

all_total_quantity = all_total_quantity + _quantity

all_total_price = all_total_price + _quantity * row['price']

session['all_total_quantity'] = all_total_quantity

session['all_total_price'] = all_total_price

return redirect(url_for('.products'))

else:

return 'Error while adding item to cart'

except Exception as e:

print(e)

finally:

cursor.close()

conn.close()

@app.route('/')

def products():

try:

conn = mysql.connect()

cursor = conn.cursor(pymysql.cursors.DictCursor)

cursor.execute("SELECT * FROM product")

rows = cursor.fetchall()

return render_template('products.html', products=rows)

except Exception as e:

print(e)
finally:

cursor.close()

conn.close()

@app.route('/empty')

def empty_cart():

try:

session.clear()

return redirect(url_for('.products'))

except Exception as e:

print(e)

@app.route('/delete/<string:code>')

def delete_product(code):

try:

all_total_price = 0

all_total_quantity = 0

session.modified = True

for item in session['cart_item'].items():

if item[0] == code:

session['cart_item'].pop(item[0], None)

if 'cart_item' in session:

for key, value in


session['cart_item'].items():

individual_quantity =
int(session['cart_item'][key]['quantity'])
individual_price =
float(session['cart_item'][key]['total_price'])

all_total_quantity =
all_total_quantity + individual_quantity

all_total_price =
all_total_price + individual_price

break

if all_total_quantity == 0:

session.clear()

else:

session['all_total_quantity'] = all_total_quantity

session['all_total_price'] = all_total_price

#return redirect('/')

return redirect(url_for('.products'))

except Exception as e:

print(e)

def array_merge( first_array , second_array ):

if isinstance( first_array , list ) and isinstance( second_array ,


list ):

return first_array + second_array

elif isinstance( first_array , dict ) and


isinstance( second_array , dict ):

return dict( list( first_array.items() ) +


list( second_array.items() ) )

elif isinstance( first_array , set ) and isinstance( second_array ,


set ):

return first_array.union( second_array )


return False

if __name__ == "__main__":

app.run()

G. Creating Template File


Now create products.html file and put it under templates directory.
Notice how we are using flask EL expression to use variable to show data into HTML
file.
We have added a link using which a user will be able to empty cart and this link is
displayed only when at least one product is added to the cart.
We also check for any success or error message and display them. We display
messages from flash scope and for this we need session and for session we need secret
key and that’s why I have configured Secret Key in app.py script.
Finally we show the products into HTML page.
<!DOCTYPE html>

<html>

<head>

<title>Python Flask Simple Shopping Cart</title>

<link href="{{ url_for('static', filename='css/style.css') }}"


rel="stylesheet" type="text/css" />

</head>

<body>

<div>

{% with messages = get_flashed_messages() %}

{% if messages %}

<ul class=flashes>

{% for message in messages %}

<li>{{ message }}</li>

{% endfor %}
</ul>

{% endif %}

{% endwith %}

</div>

<div id="shopping-cart">

<div class="txt-heading">Shopping Cart</div>

{% if 'cart_item' in session %}

<a id="btnEmpty"
href="{{ url_for('.empty_cart') }}">Empty Cart</a>

<table class="tbl-cart" cellpadding="10"


cellspacing="1">

<tbody>

<tr>

<th style="text-align:left;">Name</th>

<th style="text-align:left;">Code</th>

<th style="text-align:right;" width="5%">Quantity</th>

<th style="text-align:right;" width="10%">Unit Price</th>

<th style="text-align:right;" width="10%">Price</th>

<th style="text-align:center;" width="5%">Remove</th>

</tr>

{% for key, val in session['cart_item'].items() %}

{% set quantity = session['cart_item'][key]['quantity'] %}

{% set price = session['cart_item'][key]['price'] %}

{% set item_price = session['cart_item'][key]['total_price'] %}


<tr>

<td><img src="/static/images/{{ session['cart_item'][key]


['image'] }}" class="cart-item-image" />{{ session['cart_item'][key]
['name'] }}</td>

<td>{{ session['cart_item'][key]['code'] }}</td>

<td style="text-align:right;">{{ quantity }}</td>

<td style="text-align:right;">₹ {{ price }}</td>

<td style="text-align:right;">₹ {{ item_price }}</td>

<td style="text-align:center;">

<a href="{{ url_for('.delete_product', code=session['cart_item']


[key]['code']) }}" class="btnRemoveAction">

<img src="/static/images/icon-delete.png" alt="Remove Item" />

</a>

</td>

</tr>

{% endfor %}

<tr>

<td colspan="2" align="right">Total:</td>

<td align="right">{{ session['all_total_quantity'] }}</td>

<td align="right" colspan="2"><strong>₹


{{ session['all_total_price'] }}</strong></td>

<td></td>

</tr>

</tbody>

</table>
{% else: %}

<div class="no-records">Your Cart is Empty</div>

{% endif %}

</div>

<div id="product-grid">

<div class="txt-heading">Products</div>

{% for product in products %}

<div class="product-item">

<form method="post" action="/add">

<div class="product-image"><img
src="/static/images/{{ product.image }}"></div>

<div class="product-tile-footer">

<div class="product-title">{{ product.name }}</div>

<div class="product-price">₹
{{ product.price }}</div>

<div class="cart-action">

<input type="hidden" name="code"


value="{{ product.code }}"/>

<input type="text" class="product-quantity"


name="quantity" value="1" size="2" />

<input type="submit" value="Add to Cart"


class="btnAddAction" />

</div>

</div>

</form>

</div>
{% endfor %}

</div>

</body>

</html>

H. Testing the Application


Now navigate to the project root directory from command line tool and execute the
command python main.py, your server will start on default port 5000.
If you want to change the port then you can change the
line app.run() to app.run(port=50001), where 5001 is the new port.
Home Page
Hit URL http://localhost:5000/ in the browser, you will see below output on the
browser:

Cart Items

S-ar putea să vă placă și