FAQ¶
《Flask Web开发实战》的读者经常提出的问题与回答,如果你想提一个问题,请创建 discussion。
Exception: Install 'email_validator' for email validation support.¶
WTForms 新版本引入了破坏性变动,Email 验证通过外部库 email-validator 实现,因此需要手动安装这个库:
$ pip install email-validator
如果你使用 Pipenv,则将上述命令中的 pip 更换为 pipenv。
详见 https://stackoverflow.com/a/65056202/5511849
渲染模板报错 jinja2.exceptions.TemplateNotFound: bootstrap/form.html¶
一般是安装错了依赖导致。本书中使用的用来集成 Bootstrap 的扩展名称为 Bootstrap-Flask,而不是 Flask-Bootstrap。容易产生误解的是,为了遵循 Flask 扩展开发规范(要求扩展的包名称为 flask_foo 形式),同时也为了方便从 Flask-Bootstrap 迁移,所以 Bootstrap-Flask 的包名称为 flask_bootstrap。出现上述错误多是因为安装了 Flask-Bootstrap 导致,你需要先卸载它,然后再安装 Bootstrap-Flask:
$ pip uninstall flask-bootstrap
$ pip install bootstrap-flask
如果很不幸你同时安装了这两个扩展,那么需要全部卸载然后重新安装 Bootstrap-Flask:
$ pip uninstall flask-bootstrap bootstrap-flask
$ pip install bootstrap-flask
如果你使用 Pipenv,则将上述命令中的 pip 更换为 pipenv。
第 9 章验证邮件部分,点击邮件里的验证链接无法通过验证,提示 token invalid¶
回退 Werkzeug 版本到书中注明的 0.14.1 可解决。
第 6 章 Sendgrid 使用报错¶
在第 6 章,如果执行 sendgrid 部分的代码出现如下报错:
TypeError: <function Email at 0x7fce5c021e18> is not JSON serializable
AttributeError:list object has no attrribute _type
TypeError: __init__() got an unexpected keyword argument 'apikey'
统一的解决方法均为回退 sendgrid-python 到书中注明的 5.3.0 版本。
执行 flask run
提示找不到程序¶
执行以下检查:
* 安装了所有依赖,包括开发依赖(使用 pipenv install --dev
)
* 当前目录在项目根目录,对于第一部分的 6 个示例程序来说,切换到每个程序各自的根目录。遵循每章开头的安装命令。
* 确保没有在上层目录创建 .env 和 .flaskenv 文件。
执行 flask run
报错 AttributeError: 'module' object has no attribute 'SSLContext'
¶
升级 Python 到 2.7.9 或以上版本。
执行 flask shell 命令的时候,怎么调用 ipython,而不是默认的 Python Shell?¶
安装 flask-shell-ipython 库。
执行pipenv install
等命令出现TypeError
、ResourceWarning
、或ImportError
异常¶
新版本修复了这些问题,可以通过下面的命令升级pipenv和pip:
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade pipenv
启动程序(flask run)出现TypeError: environment can only contain strings
异常¶
使用下面的命令更新 python-dotenv 到最新版本即可解决:
$ pip install -U python-dotenv
Jinja宏里为什么可以直接使用kwargs?¶
宏默认会自定接受额外的关键字参数,在宏内部你可以直接使用 kwargs 字典来获取这些额外的关键字参数。这里直接把这个字典传入 url_for() 函数。
顺便说一下,Jinja 宏传入关键字参数的实现有一点不太符合直觉。在定义宏的时候,并不需要传入 **kwargs
。在宏的内部,你可以直接通过kwargs
字典来获取所有传入的关键字参数。
也就是说,是 Jinja 自动处理这些传入的关键字参数的。另一个宏内部可以直接使用的变量是varargs
,这个元组存储所有传入的额外位置参数,即 *args
。
helloflask仓库没有Git标签?¶
前言里在介绍Git基本用法时使用helloflask仓库作为示例,但是git tag -n命令给出位置容易产生误解。
helloflask并不包含Git标签,所以这里的命令不会输出内容。这个命令用于列出第二部分的5个项目中设置的Git标签。
如何通过PyCharm配置通过Flask-Script启动程序¶
目前不建议继续使用Flask-Script,Flask内置的CLI组件已经基本能够替代它。如果仍然要使用Flask-Scirpt,可以参考下图:
原图来自Flask学习笔记-PyCharm配置使用Flask-Script启动以及开启Debug模式。
使用Anaconda时如何通过Pipenv创建虚拟环境¶
Anaconda我没用过,简单了解了一下,觉得很成熟和方便。不过,因为书中的示例程序的依赖都写在了Pipfile里,目前似乎只有Pipenv支持从Pipfile读写依赖信息(?)。Pipenv作为未来Python官方推荐的包依赖和环境管理工具,你也可以尝试一下。 这里出错通常是因为默认的Python解释器(即Anaconda内置的第三方Python发行版)和virtualenv不兼容。你可以使用下面的命令尝试一下:
pipenv --python /usr/local/bin/python3
PyCharm无法配置运行程序,没有Module下拉选项¶
旧版本的PyCharm不支持通过模块来执行命令。新版本的PyCharm在图1-6的第4点位置有一个下拉选项,可以选择Module name,而不是Script。如果你使用的PyCharm没有这个下拉选项,可以通过为Python解释器选项一栏(Interpreter options)添加-m选项可以起到类似的效果,即python -m flask run。
为什么没有使用Flask-RESTful编写Web API?¶
在写作Web API这部分内容时,我考察了目前所有流行的API编写扩展,其中相对处于活跃开发状态的有Flask-RESTful、Flask-apispec、Flask-Classful、Flask-RestPlus、Flask-Restless这几个。第10章的程序一开始是使用Flask-RESTful的,但后来经过再三考虑,改为单纯用Flask实现。
Flask-RESTful以及它的fork改良版Flask-RESTplus中的请求解析、响应格式化已经不推荐使用,而请求解析部分也将在未来移除,假如不使用这两部分功能,那么已经没有太大必要采用这个扩展,这是我没有使用它们的主要原因;而Flask内置的MethodView已经基本能够替代Flask-Classful,而且这个扩展看起来不太灵活;Flask-RESTless依赖于SQLAlchemy,不便于在作为一个作为示例用途的程序中使用;至于Flask-apispec,它结合了webargs和marshmallow,也提供了API文档生成功能,的确是非常好的选择,我很看好这个扩展,但是因为其刚刚出现不久,还不够完善,所以也没有选用。
为什么不叫REST API而使用Web API¶
有些读者可能不理解我为什么把常说的REST API/RESTful API说成Web API,我摘取书里的这部分内容供你参考一下:
“仅仅通过HTTP协议返回JSON或XML数据的Web API并不能算是严格意义上的REST API。REST的提出者也在博文( http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven )中指出不是使用了HTTP的API都叫REST API。为了避免产生混乱,本章会尽量避免REST这个词。事实上,我们不必完全按照REST的架构要求来设计API。要尽量从API的自身特点和普适的规范来设计,而不是拘泥于REST一词。”
执行flask forge
命令后显示no such command
¶
在部分程序中,faker被列为开发依赖,所以在安装依赖时需要添加--dev选项,即:
$ pipenv install --dev
第10章Todoism启动后语言切换无效¶
需要在启动程序前执行下面的命令生成MO文件:
$ flask translate compile