1.flask网页表单

简单介绍

在本文开始前,先简单了解下flask。Flask 项目在 2025 年全年发布了两次,两次都是 2024 年 11 月发布的 3.1.0 版本的补丁版本。在GitHub上的那些未合并就已关闭的拉取请求在2025年中占到了约72%(2025年之前都为30%左右。对此有两种可能,一种是flask的维护者认为项目已经相当完整,因此对社区贡献兴趣降低;另一方面是2025年许多开发者开始使用生成式AI工具创建拉取请求。

总之,对于想要搭建自己的个人博客、学习python等开发知识的人来说是非常合适的。

开始前准备

安装python、创建虚拟环境以及flask并运行一个简单的hello world!。我相信对于你来说这些不是问题,因此接下来我简单介绍一下flask的结构后直接进入正题,关于其他方面的准备将在项目遇到时进行解决(我相信这样能够更加深入的了解开发流程)。

以下为项目开始时的结构

myblog/ #项目名称
  venv/
  app/
    __init__.py #应用工厂函数和Flask应用初始化
    routes.py #路由定义文件,包含所有URL路由和视图函数
  myblog.py #应用入口点/启动脚本
  templates/ #Jinja2模板目录,存储HTML模板文件
  static/ #静态文件目录,存储CSS、JavaScript、图片等

网页表单

在flask中通过flask-WTF扩展来使用python类表示网页表单,在使用flask及其扩展时需要为其设置SECRET_KEY来免受CSRF的恶意攻击,在开发中建议创建app/config.py文件来通过python类存储配置变量

#app/config.py
import os
basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
#获取当前文件上两级目录的绝对路径

class Config:
    SECRET_KEY = os.getenv('SECRET_KEY') or 'you-will-never-guess'

现在你可以在根目录创建.env文件来安全地放置你的私密变量,当然要想使其真正生效你需要导入第三方包python-dotenv

创建用户登录表单

#app/forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])
    password = PasswordField('密码', validators=[DataRequired()])
    remember_me = BooleanField('记住我')
    submit = SubmitField('登录')

创建好模板后别忘了你的模板templates/login.html(jinja2支持继承)和你的视图函数('/login')。

2.数据库

通过创建各种网页表单,接下来就需要能够高效检索的持久数据,因此需要使用flask的第二个扩展包Flask-SQLAlchemy(ORM),SQLAlchemy包使应用程序能够使用高级实体(如类、对象和方法)来管理数据库,而非表和SQL。ORM的工作是将高层作转换为数据库命令。

为了在开发时方便的管理数据库,我们还需要用到数据库迁移扩展Flask-Migrate

SQlAlchemy:

#app/models.py
from typing import Optional
import sqlalchemy as sa
import sqlalchemy.orm as so
from app import db

class User(db.Model):
    id: so.Mapped[int] = so.mapped_column(primary_key=True)
    username: so.Mapped[str] = so.mapped_column(sa.String(64), index=True,
                                                unique=True)
    email: so.Mapped[str] = so.mapped_column(sa.String(120), index=True,
                                             unique=True)
    password_hash: so.Mapped[Optional[str]] = so.mapped_column(sa.String(256))

    def __repr__(self):
        return '<User {}>'.format(self.username)
#__repr__方法告诉 Python 如何打印此类对象,这对调试非常有用

#当然,如果你熟悉orm也可以使用传统声明方式(使用db.Column)

在上述代码中提到了调试,为了方便调试,flask提供了flask shell命令。

数据库迁移

创建迁移仓库

flask db init

此命令会生成新的文件夹migrations/,里面有几个文件和版本子目录。从现在起,所有这些文件都应被视为项目的一部分,特别是应与应用代码一起添加到源代码控制中.

首次数据库迁移

flask db migrate -m "users table"

生成的迁移脚本现在是你项目的一部分,如果你用的是 git 或其他源控工具,它需要作为额外的源文件,和迁移目录中存储的所有其他文件一起。

该命令不会对数据库做任何更改,它只是生成迁移脚本。

要将更改应用到数据库中,必须使用以下命令:

flask db upgrade

降级数据库命令,并删除迁移脚本:

flask db downgrade