项目结构
- blueprint/views 存放各个路由映射模块
- static 存放静态文件
- templates 存放jinjia模板
- config 存放配置文件信息
- config.py app配置信息
- db_config.py 数据库配置信息
- app.py 入口文件
- decorator.py 装饰器文件
- exts.py 扩展文件
- models.py ORM文件
功能简述
- 用户注册后生成账号
- 登录账号
- 参与心理测试
- 心理测试结果发送到用户邮箱
数据库
数据库配置
数据库配置
将config信息单独提取到config文件下进行配置:
1 | SECRET_KEY = 'oh its secrect key' # flask.session需要用到的密钥 |
1 | HOSTNAME = "127.0.0.1" |
1 | from config import db_config, config |
exts.js
如果我们把db的创建放在app文件中,如下代码:
1 | db = SQLAlchemy() |
同时,如果想migrate在进行数据迁移时注意到ORM模型的更新,就必须要在app.py中引用模型类:
1 | from models import UserModel, EmailModel, TestModel, OptionModel, ResultModel |
在models.py中,为了使ORM模型继承db.Model类,也必须将db引入:
1 | from app import db |
这时,引用循环的问题就出现了:
1 | ImportError: cannot import name 'XXX' from partially initialized module 'XXX' (most likely due to a circular import) |
db的更新与从models中引用来的模型相关,
而models中的模型又与db的Model类相关,
此处需要引入扩展文件exts.py,
专门用于创建一些app需要用到的扩展对象
1 | from flask_sqlalchemy import SQLAlchemy |
ORM映射
ORM
EmailModel
OptionModel
Blueprint视图拆分
Blueprint蓝图 color
Blueprint可以为路由、视图、静态文件等需要url映射的功能提供便捷的模块拆分方法
在blueprint文件夹下创建视图模块文件:
1 | from flask import Blueprint |
blueprint文件下的蓝图对象需要在app中注册
1 | from blueprint.index import index |
wtforms 表单验证
wtforms主要用于验证前端提交的数据是否符合规范
flask-wtf是flask对wtforms的封装
wtforms的使用步骤如下:
- 定义表单
- 注意表单项name字段要和验证类中的验证属性名对应
- 定义验证类
- 一定要继承自wtforms.Form类
- 验证属性
- 验证方法
- 需要用validate_验证属性名的格式为方法命名
- 方法必须包含self和field两个参数,用field访问获取验证属性值,用self访问其他字段
- 使用验证类
1 | <form action="" method="post"> |
1 | import wtforms |
1 | from .forms import RegisterForm |
werkzeug
WSGL
WSGL Web Server Gateway Interface
WSGL是Python Web应用程序和Web服务器之间的标准接口
Werkzeug是python提供的WSGL库
使用werkzeug.security进行数据加密
- generate_password_hash 加密
- check_password_hash 比较加密数据和未加密数据是否包含相同信息
1 | from werkzeug.security import generate_password_hash, check_password_hash |
1 |
|
钩子函数
Flask中的钩子函数使用装饰器的形式定义
一些常用的钩子函数
- before_request 请求之前、视图函数执行之前
- after_request 请求之后、响应发送给用户之前调用
- teardown_request 请求之后、响应发送给用户之后调用
- before_first_request 应用启动时/处理第一个请求之前调用
- after_request 应用关闭时/处理最后一个请求之后调用
before_request使用
1 | # 请求之前全局存入用户信息 |
Decorator装饰器
装饰器
装饰器实际上是对函数的包装操作的语法糖,
装饰器函数接收一个函数参数,并返回一个新的函数作为输出,
接收的参数类似于callback回调函数
flask提供了一些常用的装饰器:如
@app.errorhandler(error_code) 定义错误处理的装饰器
1 |
|
@app.context_processor 上下文处理器
存放在上下文处理器中的变量值能在所有模板中获取到
1 |
|
自定义装饰器
1 | def my_decorator(func): # func即被包装的函数 |
1 |
session
session对象用于在Client和Server之前存储用户会话数据
默认情况下,Flask使用签名的cookie来实现会话存储(浏览器端),
而不是存储在服务器端

为了进行cookie加密,需要配置会话密钥
1 | app.secret_key = 'your_secret_key' |
session的常见操作
新增/修改session值
1 | session['key'] = value |
获取session数据
1 | temp = session.get('key') |
删除session数据
1 | session.pop('key', None) # 删除键为key的会话数据 |
SMTP邮件服务
如何在flask项目中发送邮件给指定邮箱
- 获取POP3/SMTP/IMAP服务授权码
- 初始化邮箱连接对象
- 配置邮件服务参数
- 在入口文件app.py中注入邮件服务配置
- 发送邮件
和数据库连接对象一样,邮箱连接对象一般也放在扩展文件exts.py中,
需要使用到flask_mail扩展库
Flask-Mail
Flask-Mail支持在flask应用中方便的发送电子邮件,
包括如下功能:
- 简单文本邮件发送
- jinjia2模板发送html邮件
- MIME附件(图片/文档)
- 异步发送邮件
1 | from flask_mail import Mail |
1 | # 邮件服务的服务器地址 |
1 | from config import mail_config |
发送时会使用到flask_mail.Message类
Message邮件常用属性
- sender 发送者
- recipients 接收者
- subject 主题
- body 纯文本邮件内容
- html HTML邮件内容
- attach 添加附件
添加附件时需注意,代码中读取附件文件的路径是相对于执行该应用程序的当前工作目录的,
即项目主入口app.py所在的文件路径
1 | with open('static/img/makima.png','rb') as f: |
1 | from exts import mail |