匠心精神 - 良心品质腾讯认可的专业机构-IT人的高薪实战学院

咨询电话:4000806560

Python项目实战:基于Flask的在线商城开发

Python 项目实战: 基于 Flask 的在线商城开发

Python 是一门优秀的编程语言,在 Web 开发领域中也应用广泛。其中,Flask 是一个简单而灵活的 Python Web 框架,可以帮助开发者快速地构建 Web 应用程序。本篇文章将介绍如何使用 Flask 构建一个简单的在线商城,主要包括以下几个方面内容。

### 项目概述

我们将基于 Flask 构建一个在线商城,包含商品展示、购买、支付等基本功能。

对于该项目,我们需要掌握以下技术知识:

- Flask Web 开发框架
- Jinja2 模板引擎
- SQLAlchemy 数据库 ORM
- WTForms 表单处理库
- Flask-WTF 表单扩展库
- Flask-Login 用户认证库

### 项目环境

在开始项目前,需要配置好 Python 的开发环境。可以使用 virtualenv 创建一个虚拟环境:

```shell
$ virtualenv venv
$ source venv/bin/activate
```

接下来,需要安装 Flask 及其相关扩展:

```shell
$ pip install Flask
$ pip install Jinja2
$ pip install SQLAlchemy
$ pip install WTForms
$ pip install Flask-WTF
$ pip install Flask-Login
```

### 项目结构

在线商城的项目结构如下:

```
online-shop/
    ├── app/
    │   ├── static/
    │   │   ├── css/
    │   │   │   ├── main.css
    │   │   ├── js/
    │   │   │   ├── main.js
    │   ├── templates/
    │   │   ├── base.html
    │   │   ├── home.html
    │   │   ├── login.html
    │   │   ├── product.html
    │   │   └── register.html
    │   ├── __init__.py
    │   ├── forms.py
    │   ├── models.py
    │   ├── routes.py
    │   ├── config.py
    │   └── extensions.py
    ├── run.py
    └── requirements.txt
```

其中,`app` 文件夹是项目的主要代码目录,包含了应用程序的模板、视图、数据库模型以及配置信息。`static` 文件夹存放静态资源,如 CSS、JavaScript、图片等。`templates` 文件夹存放 HTML 模板文件。`run.py` 是启动应用程序的入口文件。`requirements.txt` 是项目依赖的 Python 库列表。

### 数据库设计

在线商城需要使用数据库来存储商品信息、用户信息以及订单信息。本项目中,我们选择使用 MySQL 数据库,采用 SQLAlchemy ORM 来进行数据访问。

首先需要在 MySQL 中创建一个名为 `online_shop` 的数据库。然后,定义数据库模型如下:

```python
from app.extensions import db
from flask_login import UserMixin

class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    price = db.Column(db.Float, nullable=False)
    description = db.Column(db.String(256), nullable=False)
    image_url = db.Column(db.String(256), nullable=False)

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, nullable=False)
    email = db.Column(db.String(128), unique=True, nullable=False)
    password = db.Column(db.String(128), nullable=False)
    orders = db.relationship('Order', backref='user', lazy=True)

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False)
    quantity = db.Column(db.Integer, nullable=False)
    total_price = db.Column(db.Float, nullable=False)
```

其中,`Product` 表用于存储商品信息,包括商品名称、价格、描述、图片 URL 等。`User` 表用于存储用户信息,包括用户名、电子邮件地址、密码等。`Order` 表用于存储订单信息,包括用户ID、商品ID、购买数量以及总价。

### 视图函数

在线商城的视图函数主要包括商品展示、购买、支付等功能。其中,需要使用到 Flask 的模板引擎 Jinja2 来渲染 HTML 页面,也需要使用 Flask-WTF 扩展库来处理用户注册和登录表单。此外,为了保障用户信息的安全,我们还需要使用 Flask-Login 扩展库来进行用户认证和授权。

在本项目中,定义了如下视图函数:

```python
from app import app, db
from app.forms import RegistrationForm, LoginForm
from app.models import User, Product, Order
from flask import render_template, url_for, redirect, flash
from flask_login import login_user, logout_user, login_required, current_user

@app.route('/')
def home():
    products = Product.query.all()
    return render_template('home.html', products=products)

@app.route('/product/')
@login_required
def product(product_id):
    product = Product.query.get_or_404(product_id)
    return render_template('product.html', product=product)

@app.route('/buy/', methods=['GET', 'POST'])
@login_required
def buy(product_id):
    product = Product.query.get_or_404(product_id)
    order = Order.query.filter_by(product_id=product.id, user_id=current_user.id).first()
    if order:
        order.quantity += 1
        order.total_price += product.price
        db.session.commit()
    else:
        order = Order(product_id=product.id, user_id=current_user.id, quantity=1, total_price=product.price)
        db.session.add(order)
        db.session.commit()
    return redirect(url_for('cart'))

@app.route('/cart')
@login_required
def cart():
    orders = Order.query.filter_by(user_id=current_user.id)
    return render_template('cart.html', orders=orders)

@app.route('/remove/')
@login_required
def remove(order_id):
    order = Order.query.get_or_404(order_id)
    db.session.delete(order)
    db.session.commit()
    return redirect(url_for('cart'))

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid email address or password')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('home'))
    return render_template('login.html', title='Sign In', form=form)

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('home'))
```

其中,`home` 函数负责显示所有商品,`product` 函数负责显示单个商品的详细信息,`buy` 函数负责将商品添加到购物车中,`cart` 函数负责显示当前用户的购物车,`remove` 函数负责从购物车中删除项,`register` 函数负责用户注册,`login` 函数负责用户登录,`logout` 函数负责用户注销。

### 表单处理

为了实现用户注册和登录功能,我们需要使用到 Flask-WTF 扩展库来处理用户注册和登录表单。

在 `forms.py` 文件中,定义了如下表单类:

```python
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField('Repeat Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Register')

class LoginForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField('Sign In')
```

其中,`RegistrationForm` 类用于处理用户注册表单,包括用户名、电子邮件地址、密码等。`LoginForm` 类用于处理用户登录表单,包括电子邮件地址、密码以及是否记住用户登录状态等。

### 用户认证和授权

为了保障用户信息的安全,需要使用 Flask-Login 扩展库来进行用户认证和授权。

在 `extensions.py` 文件中,定义了如下应用程序扩展:

```python
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

db = SQLAlchemy()
login = LoginManager()
login.login_view = 'login'
```

其中,`db` 变量是 SQLAlchemy 数据库 ORM 对象,用于操作 MySQL 数据库。`login` 变量是 Flask-Login 对象,用于进行用户认证和授权。`login.login_view` 变量指定了用户未经认证时跳转到登录页面。

在 `__init__.py` 文件中,进行应用程序扩展的初始化操作:

```python
from flask import Flask
from app.config import Config
from app.extensions import db, login

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    db.init_app(app)
    login.init_app(app)

    from app.routes import home, product, buy, cart, remove, register, login, logout
    app.register_blueprint(home)
    app.register_blueprint(product)
    app.register_blueprint(buy)
    app.register_blueprint(cart)
    app.register_blueprint(remove)
    app.register_blueprint(register)
    app.register_blueprint(login)
    app.register_blueprint(logout)

    return app
```

其中,`create_app` 函数用于创建 Flask 应用程序对象,并初始化数据库 ORM 和用户认证对象。由于应用程序比较复杂,使用了蓝图(Blueprint)来分离不同模块的视图函数。

### 运行应用程序

在 `run.py` 文件中,启动了 Flask 应用程序:

```python
from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run()
```

运行项目时,需要使用 Flask-WTF 扩展库自动生成 CSRF 保护字段,可以在 HTML 页面中使用如下代码:

```html
{{ form.csrf_token }} ...
``` 此外,还需要在 MySQL 数据库中创建一个管理员账号,在 `models.py` 文件中增加如下代码: ```python from werkzeug.security import generate_password_hash admin = User(username='admin', email='admin@example.com', password=generate_password_hash('admin')) db.session.add(admin) db.session.commit() ``` 以上就是基于 Flask 的在线商城开发的详细介绍。通过本项目的实战,可以更深入地了解 Flask Web 开发框架的使用,包括 Web 应用程序的开发流程、数据库操作、用户认证和授权等方面的实践。