前言:
本篇继续在前一篇的基础上实现
之前实现一个简单的删除功能,细心的小伙伴会注意到,删除成功后,浏览器中的URL仍在引用删除操作,一旦用户进行了刷新操作,可能会复制提交删除请求,这并不是我们想要的。本次,我们增加重定向,解决这方面的问题
一、修改控制器源码
1..编辑src/books.cpp,以修改delete_obj方法如下
void Books::delete_obj(Context *c)
{
QVariantHash book = c->stash("object").toHash();
QString statusMsg;
// Delete the object on the database
QSqlQuery query = CPreparedSqlQueryThreadForDB("DELETE FROM book WHERE id = :id", "MyDB");
query.bindValue(":id", book.value("id"));
if (query.exec()) {
// Set a status message to be displayed at the top of the view
statusMsg = "Book deleted.";
} else {
// Set an error message to be displayed at the top of the view
statusMsg = query.lastError().text();
}
// Redirect the user back to the list page. Note the use
// of actionFor as earlier in this section (BasicCRUD)
c->response()->redirect(c->uriFor(CActionFor("list"), ParamsMultiMap{
{"status_msg", statusMsg }
}));
}
利用uriFor在ParamsMultiMap中包含任意数量的名称/值对的能力,在删除完成后,给浏览器返回一些参数
二、修改包装模板
在root/src/wrapper.html中,将状态消息作为查询参数处理,修改如下
...
<div id="content">
{% comment %} Status and error messages {% endcomment %}
<span class="message">{{ status_msg }}{{ c.request.queryParams.status_msg|escape }}</span>
<span class="error">{{ error_msg }}</span>
{% comment %} This is where Grantlee will stick all of your template's contents.{% endcomment %}
{{ content }}
</div><!-- end content -->
...
三、编译并测试
直接编译,生成动态库,并运行服务
在浏览器中访问http://localhost:3000/books/list
运行如下所示
点击一个删除,会减少一行,显示如下
这样再刷新,就不会发送重复删除了
本测试源码下载
后记:
到目前为止,基本的增、删、查、改功能已实现
下一篇,笔者探究认证相关的内容