Flask 实战:35、在视图函数里操作数据库
资源编号:75886 Python Web Flask Web开发实战:入门、进阶与原理解析 热度:33
在视图函数里操作数据库的方式和我们在Python Shell中的练习大致相同,只不过需要一些额外的工作。比如把查询结果作为参数传入模板渲染出来,或是获取表单的字段值作为提交到数据库的数据。在这一节,我们将把上一节学习的所有数据库操作知识运用到一个简单的笔记程序中。这个程序可以让你创建、编辑和删除笔记,并在主页列出所有保存后的笔记。
``` 其他input元素则通过value属性来设置输入框中的值,比如: ``` ``` 使用WTForms可以省略这些步骤,当我们渲染表单字段时,如果表单字段的data属性不为空,WTForms会自动把data属性的值添加到表单字段的value属性中,作为表单的值填充进去,我们不用手动为value属性赋值。因此,将存储笔记原有内容的note.body属性赋值给表单body字段的data属性即可在页面上的表单中填入原有的内容。 模板的内容基本相同,这里不再赘述。最后的工作是在主页笔记列表中的每个笔记内容下添加一个编辑按钮,用来访问编辑页面: ``` {% for note in notes %}

{{ note.body }}

Edit
{% endfor %} ``` 生成edit_note视图的URL时,我们传入当前note对象的id(note.id)作为URL变量note_id的值。 # 4.Delete 在程序中,删除的实现也非常简单,不过这里经常会有一个误区。大多数人通常会考虑在笔记内容下添加一个删除链接: ``` Delete ``` 这个链接指向用来删除笔记的delete_note视图: ``` @app.route('/delete/') def delete_note(note_id): note = Note.query.get(note_id) db.session.delete(note) db.session.commit() flash('Your note is deleted.') return redirect(url_for('index')) ``` 虽然这一切看起来都很合理,但这种处理方式实际上会使程序处于CSRF攻击的风险之中。我们在第2章曾强调过,防范CSRF攻击的基本原则就是正确使用GET和POST方法。像删除这类修改数据的操作绝对不能通过GET请求实现,正确的做法是为删除操作创建一个表单,如下所示: ``` class DeleteNoteForm(FlaskForm): submit = SubmitField('Delete') ``` 这个表单类只有一个提交字段,因为我们只需要在页面上显示一个删除按钮来提交表单。删除表单的提交请求由delete_note视图处理,如代码清单所示。 ``` @app.route('/delete/', methods=['POST']) def delete_note(note_id): form = DeleteForm() if form.validate_on_submit(): note = Note.query.get(note_id) # 获取对应记录 db.session.delete(note) # 删除记录 db.session.commit() # 提交修改 flash('Your note is deleted.')  else: abort(400) return redirect(url_for('index')) ``` 在delete_note视图的app.route()中,methods列表仅填入了POST,这会确保该视图仅监听POST请求。 和编辑笔记的视图类似,这个视图接收note_id(主键值)作为参数。如果提交表单且通过验证(唯一需要被验证的是CSRF令牌),就使用get()方法查询对应的记录,然后调用db.session.delete()方法删除并提交数据库会话。如果验证出错则使用abort()函数返回400错误响应。 因为删除按钮要在主页的笔记内容下添加,我们需要在index视图中实例化DeleteNote-Form类,然后传入模板。在index.html模板中,我们渲染这个表单: ``` {% for note in notes %}

{{ note.body }}

Edit
{{ form.csrf_token }} {{ form.submit(class='btn') }}
{% endfor %} ``` 我们将表单的action属性设置为删除当前笔记的URL。构建URL时,URL变量note_id的值通过note.id属性获取,当单击提交按钮时,会将请求发送到action属性中的URL。添加删除表单的主要目的就是防止CSRF攻击,所以不要忘记渲染CSRF令牌字段form.csrf_token。 在HTML中,标签会显示为链接,而提交按钮会显示为按钮,为了让编辑和删除笔记的按钮显示相同的样式,我们为这两个元素使用了同一个CSS类“.btn”,具体可以在static/style.css文件中查看。作为替代,你可以考虑使用JavaScript创建监听函数,当删除按钮按下时,提交对应的隐藏表单。