项目介绍与规划
在本章中,我们将带领大家创建一个简单但功能齐全的 Web 应用,通过实践来巩固前面的学习内容。我们将使用 Flask 框架,逐步实现用户注册与登录功能,以及数据展示与交互功能。最后,我们讨论如何将应用部署到云平台。
项目需求分析与功能规划
在开始编码之前,我们需要对项目进行需求分析和功能规划。以下是我们将实现的主要功能:
- 用户注册与登录
- 用户可以注册新账户
- 用户可以使用已注册账户登录
- 数据展示与交互
- 登录成功后,用户可以看到一个欢迎页面
- 用户可以查看和更新个人信息
项目目录结构的设计
为了保持代码的整洁和组织有序,我们将采用如下的目录结构:
flask_app/│├── app/│ ├── static/│ ├── templates/│ ├── __init__.py│ ├── routes.py│ └── models.py│├── venv/│├── config.py├── run.py├── requirements.txt└── README.md
开发与实现
使用 Flask 创建 Web 应用
首先,我们需要创建一个虚拟环境并安装 Flask:
# 创建虚拟环境python3 -m venv venv# 激活虚拟环境(Unix 或 macOS)source venv/bin/activate# 激活虚拟环境(Windows)venv\Scripts\activate# 安装 Flaskpip install Flask
项目初始化
在 flask_app 目录下创建 run.py 文件,并编写如下代码:
from app import create_appapp = create_app()if __name__ == '__main__':app.run(debug=True)
接着,在 app 目录下创建 __init__.py 文件,并编写如下代码:
from flask import Flaskdef create_app():app = Flask(__name__)app.config['SECRET_KEY'] = 'your_secret_key'from .routes import mainapp.register_blueprint(main)return app
实现用户注册与登录功能
创建数据库模型
在 app 目录下创建 models.py 文件,并编写如下代码:
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(150), unique=True, nullable=False)password = db.Column(db.String(150), nullable=False)
创建注册与登录路由
在 app 目录下创建 routes.py 文件,并编写如下代码:
from flask import Blueprint, render_template, redirect, url_for, request, flashfrom .models import User, dbfrom werkzeug.security import generate_password_hash, check_password_hashmain = Blueprint('main', __name__)@main.route('/')def index():return render_template('index.html')@main.route('/signup', methods=['GET', 'POST'])def signup():if request.method == 'POST':username = request.form.get('username')password = request.form.get('password')user = User.query.filter_by(username=username).first()if user:flash('Username already exists')return redirect(url_for('main.signup'))new_user = User(username=username, password=generate_password_hash(password, method='sha256'))db.session.add(new_user)db.session.commit()return redirect(url_for('main.login'))return render_template('signup.html')@main.route('/login', methods=['GET', 'POST'])def login():if request.method == 'POST':username = request.form.get('username')password = request.form.get('password')user = User.query.filter_by(username=username).first()if not user or not check_password_hash(user.password, password):flash('Invalid username or password')return redirect(url_for('main.login'))return redirect(url_for('main.profile'))return render_template('login.html')@main.route('/profile')def profile():return render_template('profile.html')
创建模板文件
在 app/templates 目录下创建以下 HTML 文件:
index.html
<!DOCTYPE html><html><head><title>Home</title></head><body><h1>Welcome to the Flask Web App!</h1><a href="{{ url_for('main.signup') }}">Sign Up</a><a href="{{ url_for('main.login') }}">Log In</a></body></html>
signup.html
<!DOCTYPE html><html><head><title>Sign Up</title></head><body><h1>Sign Up</h1><form method="POST"><label>Username:</label><input type="text" name="username" required /><label>Password:</label><input type="password" name="password" required /><button type="submit">Sign Up</button></form><a href="{{ url_for('main.login') }}">Log In</a></body></html>
login.html
<!DOCTYPE html><html><head><title>Log In</title></head><body><h1>Log In</h1><form method="POST"><label>Username:</label><input type="text" name="username" required /><label>Password:</label><input type="password" name="password" required /><button type="submit">Log In</button></form><a href="{{ url_for('main.signup') }}">Sign Up</a></body></html>
profile.html
<!DOCTYPE html><html><head><title>Profile</title></head><body><h1>Welcome to your profile page!</h1><a href="{{ url_for('main.index') }}">Home</a></body></html>
实现数据展示与交互功能
更新用户信息
在 routes.py 文件中,添加如下路由:
@main.route('/update_profile', methods=['GET', 'POST'])def update_profile():if request.method == 'POST':username = request.form.get('username')user = User.query.filter_by(username=username).first()if user:user.username = request.form.get('new_username')db.session.commit()flash('Profile updated successfully')else:flash('User not found')return redirect(url_for('main.profile'))return render_template('update_profile.html')
创建更新用户信息模板
在 app/templates 目录下创建 update_profile.html 文件,并编写如下代码:
<!DOCTYPE html><html><head><title>Update Profile</title></head><body><h1>Update Profile</h1><form method="POST"><label>Current Username:</label><input type="text" name="username" required /><label>New Username:</label><input type="text" name="new_username" required /><button type="submit">Update</button></form><a href="{{ url_for('main.profile') }}">Profile</a></body></html>
部署与发布
部署到 Heroku
- 创建
Procfile文件并添加以下内容:
web: gunicorn run:app
- 创建
requirements.txt文件:
pip freeze > requirements.txt
- 将项目推送到 GitHub 仓库:
git initgit add .git commit -m "Initial commit"git remote add origin <your_repository_url>git push -u origin master
- 在 Heroku 创建一个新的应用并部署:
heroku create <your_app_name>git push heroku master
使用 Docker 进行容器化部署
- 创建
Dockerfile文件并添加以下内容:
FROM python:3.8-slimWORKDIR /appCOPY requirements.txt requirements.txtRUN pip install -r requirements.txtCOPY . .CMD ["gunicorn", "-b", "0.0.0.0:8000", "run:app"]
- 构建 Docker 镜像并运行容器:
docker build -t flask_app .docker run -d -p 8000:8000 flask_app
- 验证应用在 Docker 容器中运行:
打开浏览器,访问http://localhost:8000,确保应用正常运行。
实现数据展示与交互功能
更新用户信息
在 routes.py 文件中,添加如下路由:
@main.route('/update_profile', methods=['GET', 'POST'])def update_profile():if request.method == 'POST':username = request.form.get('username')user = User.query.filter_by(username=username).first()if user:user.username = request.form.get('new_username')db.session.commit()flash('Profile updated successfully')else:flash('User not found')return redirect(url_for('main.profile'))return render_template('update_profile.html')
创建更新用户信息模板
在 app/templates 目录下创建 update_profile.html 文件,并编写如下代码:
<!DOCTYPE html><html><head><title>Update Profile</title></head><body><h1>Update Profile</h1><form method="POST"><label>Current Username:</label><input type="text" name="username" required /><label>New Username:</label><input type="text" name="new_username" required /><button type="submit">Update</button></form><a href="{{ url_for('main.profile') }}">Profile</a></body></html>
结论
通过本章的项目实战,我们成功创建了一个功能齐全的 Web 应用,并通过 Flask 框架实现了用户注册与登录功能,以及数据展示与交互功能。我们还学习了如何将应用部署到 Heroku 和使用 Docker 进行容器化部署。这些实践不仅巩固了我们对 Python 基础和进阶知识的理解,也为我们提供了一个完整的 Web 开发工作流示例,帮助我们更好地理解实际开发中的各个环节。
