Python3使用Flask开发Web项目新手入门开发文档
以下是一份针对新手的 Flask 开发入门文档,涵盖环境搭建、核心功能及常用模块实现,附带完整可运行代码:
Flask 新手入门开发文档
一、环境搭建
1. 安装 Python
- 下载地址:Python 官网(推荐 3.9+ 版本)
- 安装时勾选 “Add Python to PATH”
2. 创建虚拟环境
# 新建项目文件夹
mkdir flask_demo && cd flask_demo# 创建虚拟环境
python -m venv venv# 激活虚拟环境
# Windows:
venv\Scripts\activate
# Mac/Linux:
source venv/bin/activate
3. 安装 Flask 及扩展
# 基础 Flask
pip install flask# 常用扩展(后续功能会用到)
pip install flask-sqlalchemy # 数据库ORM
pip install flask-wtf # 表单处理
pip install flask-login # 用户认证
pip install requests # 网络请求(爬虫用)
pip install beautifulsoup4 # 网页解析(爬虫用)
二、Hello World 入门
1. 第一个 Flask 程序
创建 app.py
文件:
from flask import Flask# 初始化 Flask 应用
app = Flask(__name__)# 定义路由(访问 http://127.0.0.1:5000/ 时触发)
@app.route('/')
def index():return "Hello, Flask!"# 启动服务器
if __name__ == '__main__':app.run(debug=True) # debug=True 表示开发模式,自动重启
2. 运行程序
python app.py
访问 http://127.0.0.1:5000
即可看到 “Hello, Flask!”
三、项目结构规范
推荐目录结构(后续功能基于此结构开发):
flask_demo/
├── app.py # 主程序入口
├── config.py # 配置文件
├── models.py # 数据模型(数据库表)
├── routes/ # 路由模块
│ ├── __init__.py
│ ├── auth.py # 登录注册路由
│ └── file.py # 文件上传下载路由
├── static/ # 静态文件(CSS/JS/图片)
│ └── style.css
├── templates/ # 模板文件(HTML)
│ ├── base.html # 基础模板(继承用)
│ ├── login.html # 登录页面
│ └── upload.html # 文件上传页面
└── uploads/ # 上传文件存储目录
四、核心功能实现
1. 页面解析(模板渲染)
Flask 使用 Jinja2 模板引擎,支持变量、循环、条件判断等。
(1)创建基础模板 templates/base.html
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>{% block title %}Flask 示例{% endblock %}</title><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body><nav><a href="/">首页</a><a href="/login">登录</a><a href="/upload">文件上传</a></nav><div class="content">{% block content %}{% endblock %} <!-- 子模板内容会插入这里 --></div>
</body>
</html>
(2)创建子模板 templates/index.html
{% extends "base.html" %} <!-- 继承基础模板 -->{% block title %}首页{% endblock %}{% block content %}<h1>欢迎来到首页</h1><p>当前时间:{{ current_time }}</p> <!-- 接收变量 --><ul>{% for item in items %} <!-- 循环示例 --><li>{{ item }}</li>{% endfor %}</ul>
{% endblock %}
(3)渲染模板的路由(在 app.py
中添加)
from flask import render_template
from datetime import datetime@app.route('/home')
def home():# 传递变量到模板data = {'current_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'items': ['Flask', 'Python', 'Web开发']}return render_template('index.html', **data) # **data 表示将字典解析为变量
2. 表单验证(使用 Flask-WTF)
处理用户输入并验证(以登录表单为例)。
(1)创建表单类(新建 forms.py
)
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Lengthclass LoginForm(FlaskForm):# DataRequired:必填项;Length:长度限制username = StringField('用户名', validators=[DataRequired('用户名不能为空'), Length(3, 20)])password = PasswordField('密码', validators=[DataRequired('密码不能为空'), Length(6, 16)])submit = SubmitField('登录')
(2)添加表单路由(在 app.py
中添加)
from flask import request, redirect, url_for, flash
from routes.forms import LoginForm# 设置密钥(用于表单CSRF保护)
app.config['SECRET_KEY'] = 'your-secret-key-keep-safe' # 实际开发中用随机字符串@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()if form.validate_on_submit(): # 表单提交且验证通过username = form.username.datapassword = form.password.data# 这里仅做示例,实际需查询数据库验证if username == 'admin' and password == '123456':flash('登录成功!', 'success') # 显示成功消息return redirect(url_for('home')) # 跳转到首页else:flash('用户名或密码错误', 'danger') # 显示错误消息return render_template('login.html', form=form)
(3)创建登录模板 templates/login.html
{% extends "base.html" %}{% block title %}登录{% endblock %}{% block content %}<h1>用户登录</h1><form method="POST">{{ form.csrf_token }} <!-- CSRF保护 --><div>{{ form.username.label }}<br>{{ form.username(size=30) }}<br>{% for error in form.username.errors %}<span style="color: red;">{{ error }}</span>{% endfor %}</div><div>{{ form.password.label }}<br>{{ form.password(size=30) }}<br>{% for error in form.password.errors %}<span style="color: red;">{{ error }}</span>{% endfor %}</div><div>{{ form.submit() }}</div></form>
</body>
</html>
3. 用户登录注册功能(Flask-Login + SQLAlchemy)
实现用户注册、登录、登出的完整流程。
(1)配置数据库(config.py
)
import os# 数据库配置(使用SQLite,文件型数据库,无需额外安装)
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'users.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False # 关闭不必要的警告
(2)创建用户模型(models.py
)
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hashdb = SQLAlchemy()class User(UserMixin, db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(20), unique=True, nullable=False)password_hash = db.Column(db.String(128), nullable=False) # 存储加密后的密码# 设置密码(加密存储)def set_password(self, password):self.password_hash = generate_password_hash(password)# 验证密码def check_password(self, password):return check_password_hash(self.password_hash, password)
(3)初始化登录管理器(app.py
中补充)
from flask_login import LoginManager, login_user, logout_user, login_required
from models import db, User
import config# 初始化数据库
app.config.from_object(config)
db.init_app(app)# 初始化登录管理器
login_manager = LoginManager(app)
login_manager.login_view = 'login' # 未登录时跳转的页面# 加载用户(Flask-Login 要求实现)
@login_manager.user_loader
def load_user(user_id):return User.query.get(int(user_id))
(4)注册功能实现(app.py
中添加)
# 注册表单(在 forms.py 中添加)
class RegisterForm(FlaskForm):username = StringField('用户名', validators=[DataRequired(), Length(3, 20)])password = PasswordField('密码', validators=[DataRequired(), Length(6, 16)])submit = SubmitField('注册')# 注册路由(app.py 中添加)
from routes.forms import RegisterForm@app.route('/register', methods=['GET', 'POST'])
def register():form = RegisterForm()if form.validate_on_submit():# 检查用户名是否已存在if User.query.filter_by(username=form.username.data).first():flash('用户名已存在', 'danger')return redirect(url_for('register'))# 创建新用户new_user = User(username=form.username.data)new_user.set_password(form.password.data) # 加密密码db.session.add(new_user)db.session.commit()flash('注册成功,请登录', 'success')return redirect(url_for('login'))return render_template('register.html', form=form)
(5)创建注册模板 templates/register.html
(类似登录模板)
{% extends "base.html" %}{% block title %}注册{% endblock %}{% block content %}<h1>用户注册</h1><form method="POST">{{ form.csrf_token }}<div>{{ form.username.label }}<br>{{ form.username(size=30) }}<br>{% for error in form.username.errors %}<span style="color: red;">{{ error }}</span>{% endfor %}</div><div>{{ form.password.label }}<br>{{ form.password(size=30) }}<br>{% for error in form.password.errors %}<span style="color: red;">{{ error }}</span>{% endfor %}</div><div>{{ form.submit() }}</div></form>
</body>
</html>
(6)初始化数据库
在 app.py
中添加创建表的代码:
# 确保在 app 上下文内创建表
with app.app_context():db.create_all() # 首次运行时创建数据库表
4. 文件上传下载功能
(1)配置上传目录(config.py
中添加)
# 文件上传配置
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'} # 允许的文件类型
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 最大文件大小(16MB)# 创建上传目录(如果不存在)
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
(2)文件上传路由(app.py
中添加)
import os
from flask import send_from_directory# 检查文件类型是否允许
def allowed_file(filename):return '.' in filename and \filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']@app.route('/upload', methods=['GET', 'POST'])
@login_required # 需登录才能访问
def upload_file():if request.method == 'POST':# 检查是否有文件被上传if 'file' not in request.files:flash('未选择文件', 'danger')return redirect(request.url)file = request.files['file']# 检查文件名是否为空if file.filename == '':flash('未选择文件', 'danger')return redirect(request.url)# 验证文件并保存if file and allowed_file(file.filename):filename = file.filenamefilepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)file.save(filepath)flash(f'文件 {filename} 上传成功', 'success')return redirect(url_for('upload_file'))# 显示上传表单return render_template('upload.html')# 文件下载路由
@app.route('/download/<filename>')
@login_required
def download_file(filename):return send_from_directory(app.config['UPLOAD_FOLDER'],filename,as_attachment=True # 强制下载(而非浏览器打开))
(3)创建上传模板 templates/upload.html
{% extends "base.html" %}{% block title %}文件上传{% endblock %}{% block content %}<h1>文件上传</h1><form method="POST" enctype="multipart/form-data"> <!-- 注意enctype --><input type="file" name="file" accept=".txt,.pdf,.png,.jpg,.jpeg,.gif"><input type="submit" value="上传"></form><h2>已上传文件</h2><ul>{% for file in uploaded_files %}<li>{{ file }}<a href="{{ url_for('download_file', filename=file) }}">下载</a></li>{% endfor %}</ul>
{% endblock %}
(4)在上传路由中添加文件列表(app.py
中补充)
@app.route('/upload', methods=['GET', 'POST'])
@login_required
def upload_file():# 获取已上传文件列表uploaded_files = os.listdir(app.config['UPLOAD_FOLDER'])# 处理上传逻辑(同上)# ...return render_template('upload.html', uploaded_files=uploaded_files)
5. 页面爬虫功能(结合 Flask 路由)
在 Flask 中集成爬虫,爬取网页内容并展示。
(1)创建爬虫路由(app.py
中添加)
import requests
from bs4 import BeautifulSoup@app.route('/crawl')
def crawl_demo():try:# 爬取示例网页(以豆瓣电影Top250为例)url = 'https://movie.douban.com/top250'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}response = requests.get(url, headers=headers)response.raise_for_status() # 检查请求是否成功# 解析网页内容soup = BeautifulSoup(response.text, 'html.parser')movie_list = []# 提取电影标题for item in soup.select('.hd'):title = item.select_one('.title').text.strip()movie_list.append(title)return render_template('crawl.html', movies=movie_list[:10]) # 显示前10部except Exception as e:return f'爬虫出错:{str(e)}'
(2)创建爬虫结果模板 templates/crawl.html
{% extends "base.html" %}{% block title %}爬虫示例{% endblock %}{% block content %}<h1>豆瓣电影Top10</h1><ul>{% for movie in movies %}<li>{{ movie }}</li>{% endfor %}</ul>
{% endblock %}
五、运行与调试
- 确保所有文件创建完成后,启动程序:
python app.py
- 访问以下地址测试功能:
- 首页:
http://127.0.0.1:5000/home
- 注册:
http://127.0.0.1:5000/register
- 登录:
http://127.0.0.1:5000/login
- 文件上传:
http://127.0.0.1:5000/upload
- 爬虫示例:
http://127.0.0.1:5000/crawl
- 首页:
六、新手常见问题
- 模板找不到:确保模板文件放在
templates
目录下,文件名正确。 - 数据库错误:首次运行需创建表(
db.create_all()
),注意路径权限。 - 文件上传失败:检查上传目录权限,确保文件类型在允许列表中。
- 爬虫被反爬:添加
User-Agent
头,避免频繁请求同一网站。
通过以上步骤,你可以掌握 Flask 开发的核心功能,后续可根据需求扩展更多功能(如分页、搜索、API接口等)。