---------------------------------------------以下内容2017.7.14更新-----------------------------------------------------
flask web(封面上是一条狗)这本书前7章讲了flask的基本概念,在第8章开始逐渐实现一个博客网站,建议读者从这一章开始创建自己的工程,跟着书中的进度迭代自己的博客网站,而不是直接使用git clone命令从作者的示例程序中checkout当前版本,这样做会遇到一些莫名其妙的问题。
切入正题,第11章直接checkout 11a,配置好环境变量,在Terminal中upgrade数据库,用runserver参数执行manage.py,打开网站,然后注册帐号,验证,登录,最后你会发现主页上并没有文章表单,也没有作者的那句“What's on your mind?”。
原因在于:即使upgrade了数据库,但当前的数据库中没有角色实例,也就是说你注册的账户(即使是用程序中指定的邮箱注册的管理员账户)没有对应的角色的权限,因此就无法看到提示/输入框/提交按钮。下面是关于该文章表单的HTML代码,位于app/templates/index.html:
1 <div> 2 {% if current_user.can(Permission.WRITE_ARTICLES) %} 3 {{ wtf.quick_form(form) }} 4 {% endif %} 5 </div>
可以看到,只有当前登录的账户拥有“写文章”的权限,才向你展示写文章的表单。
解决办法:需要向数据库中添加角色,再进行注册/验证/登录,这样就拥有了写文章的权限。在书中第99页中间部分写的很清楚,insert_roles函数并不直接创建新角色对象,而是查找现有角色,再进行更新。这是作者为了将来拓展角色类别(比如对普通用户再进行细分)而进行的处理。下面紧接着写着:如果想把角色(指的是之前提到的用户/协管员/管理员这三个角色)写入数据库,需要使用shell会话
1 >>>Role.insert_roles()
2 >>>Role.query.all()
来对数据库中的角色进行更新,这样数据库中就有了上述三个角色。这时注册的账户就都有了对应的角色,比如你使用程序中的Flask Admin静态变量指定的邮箱注册,那么该账户自动成为管理员账户,拥有修改其他账户资料的权限。
下面是数据库模型中User类的构造函数,可以看出当账户的角色为空的时候,分支语句选择给账户绑定管理员角色或者默认角色,这里的前提是数据库中有角色,如果数据库中没有角色,就无法赋予账户对应的角色,也就没法让账户得到该有的权限,结果就是没有权限的账户看不到写文章的表单,实际上这时看到的内容只包括那些不需要任何权限的内容,比如导航栏/登录/注册这些内容。
1 def __init__(self, **kwargs): 2 super(User, self).__init__(**kwargs) 3 if self.role is None: 4 if self.email == current_app.config['FLASKY_ADMIN']: 5 self.role = Role.query.filter_by(permissions=0xff).first() 6 if self.role is None: 7 self.role = Role.query.filter_by(default=True).first() 8 if self.email is not None and self.avatar_hash is None: 9 self.avatar_hash = hashlib.md5( 10 self.email.encode('utf-8')).hexdigest()
我的环境是ubuntu16.04,使用集成开发环境pycharm,flask框架常常需要导入大量的依赖包,只需在pycharm内置的terminal中执行sudo apt-get install -r requirements/xxx.txt(xxx是包名=版本号的序列文本)即可安装所有依赖包,如果读者不查资料的话,可能读到本书203页第18章才能找到关于适合flask框架的集成开发环境的介绍,如果此前一直使用文本和终端命令进行学习,那就太辛苦了。