![a1790330dc2a0ddfdfb8bc7b918369f2.png](https://i-blog.csdnimg.cn/blog_migrate/9c97119aaa4987b7a67ee70357f37a27.jpeg)
flask是一个Python语言开发的web“微框架”,和django不同的是,它既没有数据库、也没有表单验证等工具它本身仅仅提供了一个WSGI的桥梁,其他东西统统靠你来定制,具有很大的灵活性
脚手架
为了迅速搭建一个像样的flask网站,我们可以使用脚手架
之前在Github上看到cookiecutter-flask,是个不错的选择,但是新手可能会看不懂里面代码是如何封装的
于是本人做出了一个更user-friendly的脚手架——cookiecutter-flask-bootstrap
这个脚手架的功能大致和上个脚手架差不多,不过更加轻量化,而且结构更加清晰明了,best practice也基本都做到了,希望大家用的开心:d
最后还要感谢李辉大大的狼书,给了我很大的帮助
路由
路由是将特定的业务代码(即视图函数)绑定到某个url上,以实现某个功能
注册
flask中使用装饰器来注册路由
@app.route
可以为路由传递变量,变量左边可以带转换器用来转换变量的类型
@app.route
常用的转换器有6种:string, int, float, path, any, uuid
比较特殊的是any,格式如下(var变量只接受a, b其中的任意一值)
@app.route
如果想通过路由直接访问文件呢?用path转换器和send_from_directory就行了
@app.route
构造url
使用url_for函数可以反向构建访问路由的url
url_for
HTTP
路由默认支持GET方法,如果需要POST方法则需在route的methods中传入
HTTP methods的用处如下:
- GET:获取资源
- POST:创建资源
- PUT:更新资源
- DELETE:删除资源
@app.route
如果想更改HTTP请求头内容,那就要用到make_response
比如制作网站的RSS,就需要把响应的mimetype设置为application/xml
@app.route
模板
渲染一个模板,简言之就是通过上下文变量来生成HTML
from
render_template中第一个参数是要渲染的模板文件名,其余参数则是上下文变量
通过mustache语法将上下文变量传入模板并渲染,同时也支持if、for等控制流语句语法,更高级的有过滤器、模板继承、宏等
提几个常用的过滤器:
- safe: 避免HTML的自动转义,本质上是个Markup对象
- length: 获取变量长度
- default: 为变量设置默认值
- trim: 去除变量前后的空格
- tojson: 将变量转化为json
- truncate: 截断字符串,常用于显示文章摘要
网站的静态文件放在static文件夹中,通过反向构造url访问
url_for
上下文全局变量
- current_app:指向处理请求的app实例
- g:global的简写,以object的方式存储信息(比如用户登录后的用户对象 g.user)
- request:以dict形式存储HTTP请求相关变量
- session:以dict的方式存储会话信息(比如用户登录后的用户id session['user_id'])
以下是request所封装的几个最常用的参数,全部参数请点这里
request
工具函数
- abort:放弃请求
- flash:闪现信息,可以附带类别
- jsonify:将数据序列化为json,常用于设计restful api
- redirect:重定向
工厂模式
工厂模式使得app在创建之时能同时完成以下步骤:加载配置,初始化扩展,注册蓝本,注册shell上下文,以及注册错误处理函数等
def
蓝本
用来实现模块化编程
例如一个app(名字叫flasky)通常会有以下的文件夹结构
├─
其中blueprints就是蓝本文件夹,里面存放着和templates对应的4个蓝本
├─
这4个蓝本中__init__.py负责Python的包结构,其余三个则是app的3个功能模块:认证、主页、用户
以auth.py为例
from
蓝本也可以注册路由,如果反向构造url的话就得加上蓝本名,比如url_for('auth.login')
蓝本的注册应在工厂函数中执行,并且每个蓝本可以通过url_prefix来给url添加前缀
常用插件
- flask-admin:提供admin管理后台
- flask-avatars:生成用户头像
- flask-ckeditor:集成富文本编辑器ekeditor
- flask-cors:提供跨域支持
- flask-dropzone:集成文件上传插件dropzone
- flask-login:处理用户登陆认证逻辑
- flask-mail:邮箱服务
- flask-migrate:提供数据库迁移支持
- flask-moment:提供时间规范化支持
- flask-mongoengine:集成mongoengine——面向mongodb的ORM
- flask-restful:RESTful API支持
- flask-socketio:集成socketio,常用于编写聊天室
- flask-sqlalchemy:集成sqlalchemy——面向标准SQL的ORM
- flask-weasyprint:提供PDF打印功能
- flask-whooshee:集成whooshee——全文搜索引擎
- flask-wtf:集成wtforms——表单支持
- bootstrap-flask:集成bootstrap,并提供一些有用的宏
- faker:能生成假数据,用于测试
高级玩法
强制响应格式
API返回的一般都是json,故在每个视图函数中调用jsonify将dict序列化为json
from
但其实没必要这么做,因为flask的Response是可以定制的
flask的app实例提供了response_class属性,默认是Response
继续查照定义,发现Response其实继承了werkzeug里的BaseResponse
通过查阅BaseResponse,我们可以重载Response的force_type类方法,将类型为dict的response直接jsonify,并且无需在每个视图函数中都显式调用jsonify函数了
from
当然,你也可以类似地强制响应格式为xml,RSSHub就是这么实现的
from
全局模板函数
有的时候你希望把某种逻辑抽象成一个函数,使得多个页面能共用,那么就要定义全局模板函数了
有的网站的排序功能是这么实现的:通过在url的查询字符串中追加sort(要排序的字段)和order(升序还是降序)参数,在视图函数中获取这2个参数并进行相应的排序处理
要实现这个功能,可以编写2个全局函数:1个负责修改url的查询字符串,另一个负责处理给查询排序
@bp.app_template_global
自定义路由转换器
我们都知道flask的路由映射是存储在app.url_map中的,因此查阅官方文档有关url_map的部分,就能轻松实现
from
官方文档仅仅用了逗号分隔符,而在这里我们通过添加了separator属性来实现了自定义分隔符 访问如下链接体验下效果
http://localhost:5000/list1/python+javascript+sql
http://localhost:5000/list2/python|javascript|sql