加载中...

第十章 实战演练:扩展todos到Server端(backbonejs+webpy)


上一节简单介绍了怎么使用webpy搭建一个后端的接口服务,这一节就来简单实现一下。

10.1 项目结构

首先还是来看下项目的结构,然后再一步一步的分析,结构如下:

  1. src
  2. ├── index.html
  3. ├── init_sqlite.py
  4. ├── models.py
  5. ├── server.py
  6. ├── static
  7.    ├── backbone.js
  8.    ├── destroy.png
  9.    ├── jquery.js
  10.    ├── json2.js
  11.    ├── todos.css
  12.    ├── todos.js
  13.    └── underscore.js
  14. └── todos.db

以上结构可以分为四个部分:模板、静态资源、后端逻辑处理、后端数据处理,其实最后两个都属于后端部分。

因为模板和静态资源和之前没有太大差异,因此合并在一起介绍。首先来看后端的接口。

10.2 后端接口

相对于前端的各种model、collection和view,后端显得比较简单。只需要提供可访问的接口,并且根据POST、PUT、DELETE、GET这四种操作完成对数据库的CRUD即可(Create,Read,Update,Delete)。

先来看models中的代码,这里对todo表的操作进行了简单的封装:

  1. #coding:utf-8
  2. import web
  3. db = web.database(dbn='sqlite', db="todos.db")
  4. class Todos(object):
  5. @staticmethod
  6. def get_by_id(id):
  7. return db.select('todos', where="id=$id", vars=locals())
  8. @staticmethod
  9. def get_all():
  10. return db.select('todos')
  11. @staticmethod
  12. def create(**kwargs):
  13. db.insert('todos', **kwargs)
  14. @staticmethod
  15. def update(**kwargs):
  16. db.update('todos', where="id=$id", vars={"id": kwargs.pop('id')}, **kwargs)
  17. @staticmethod
  18. def delete(id):
  19. db.delete('todos', where="id=$id", vars=locals())

代码很简单,从方法的命名上就知道要完成的功能是什么,这里不得不说一句,任何语言中好的变量或方法的命名,胜过大段的注释。

model部分没有具体的业务逻辑,只是针对数据库进行CRUD操作。下面来看给浏览器提供接口的部分。

server部分,提供了前端浏览器需要访问的接口,同时也提供了页面初始加载时的渲染页面的功能。server.py的代码如下:

  1. #coding:utf-8
  2. import json
  3. import web
  4. from models import Todos
  5. urls = (
  6. '/', 'index', #返回首页
  7. # 处理POST请求
  8. '/todo', 'todo',
  9. # 处理前端todo的请求,对指定记录进行操作
  10. '/todo/(\d*)', 'todo',
  11. # 处理前端todo的请求,返回所有数据
  12. '/todos/', 'todos',
  13. )
  14. app = web.application(urls, globals())
  15. render = web.template.render('')
  16. # 首页
  17. class index:
  18. def GET(self):
  19. # 渲染首页到浏览器
  20. return render.index()
  21. class todo:
  22. def GET(self, todo_id=None):
  23. result = None
  24. itertodo = Todos.get_by_id(id=todo_id)
  25. for todo in itertodo:
  26. result = {
  27. "id": todo.id,
  28. "title": todo.title,
  29. "order": todo._order,
  30. "done": todo.done == 1,
  31. }
  32. return json.dumps(result)
  33. def POST(self):
  34. data = web.data()
  35. todo = json.loads(data)
  36. # 转换成_order, order是数据库关键字, sqlite3报错
  37. todo['_order'] = todo.pop('order')
  38. Todos.create(**todo)
  39. def PUT(self, todo_id=None):
  40. data = web.data()
  41. todo = json.loads(data)
  42. todo['_order'] = todo.pop('order')
  43. Todos.update(**todo)
  44. def DELETE(self, todo_id=None):
  45. Todos.delete(id=todo_id)
  46. class todos:
  47. def GET(self):
  48. todos = []
  49. itertodos = Todos.get_all()
  50. for todo in itertodos:
  51. todos.append({
  52. "id": todo.id,
  53. "title": todo.title,
  54. "order": todo._order,
  55. "done": todo.done == 1,
  56. })
  57. return json.dumps(todos)
  58. if __name__ == "__main__":
  59. app.run()

相对于model.py来说,这里做了些数据转换的操作,如前端backbone通过ajax发过来的数据需要转换之后才能存入数据库,而从数据库取出的数据也要稍加处理才能符合前端todos.js中定义的model的要求。

在这个server中,提供了三个四个url,依次功能为:首页加载、单个todo创建、单个todo查询修改和删除、查询全部。分成四个也主要是依据所选框架webpy的特性。

在url之后,是对应一个具体的class,url接受到的请求将有对应的class来处理,比如说 /todo 这个url,对应的处理请求的class就是todo。另外对应浏览器端发过来的POST、GET、PUT、DELETE请求,class对应的也是相应的方法。这也是选webpy的一个原因。

说我了后端提供的接口,以及如何进行处理的原理。我们来看如何修改前端的代码,才能让数据发送到后端来。

10.3 修改todos,发送数据到后端

这个部分改动比较小,就不贴代码了。有需要的可以到 code 中看。

之前的数据是存在localstorage中,是因为引用了localStorage.js文件,并且在collection中声明了 localStorage: new Backbone.LocalStorage("todos-backbone") 。

在修改的时候有三个地方需要修改,第一是model的定义,部分代码:

  1. var Todo = Backbone.Model.extend({
  2. urlRoot: '/todo',
  3. ......

第二个就是collection的修改,去掉了localStorage的声明,并添加url:

  1. var TodoList = Backbone.Collection.extend({
  2. url: '/todos/',
  3. ......

这样就搞定了。

10.4 Demo的使用

在 code 中,如果想要把我的demo在本地运行的话,需要首先运行下 python init_sqlite.py 来初始化sqlite3的数据库,运行完之后会在本地生成一个todos.db的数据库文件。

之后,就可以通过运行 python server.py ,然后访问命令行提示的网址就可以使用了。

最后稍稍总结一下,我觉得到这一章为止,对技术比较认真、比较有追求的同学应该知道怎么通过backbonejs和webpy把前后端连起来了。所有的这些文章只是为了帮你打开一扇门,或者仅仅只是一盏灯,具体你的业务逻辑还是需要通过自己的思考来解决。妄图让别人帮你实现业务逻辑的人都是切实的不思上进的菜鸟。

另外,关于这个Todos的案例,是你在打算把Backbonejs应用于实践时必须要参考和思考的。虽然到网上搜罗一下Backbonejs项目实例 比思考要省心,但是别人的始终是别人的,你不转化成自己的,始终无法灵活运用。借此告诫那些觉得这个Todo案例没啥用的同学们。


还没有评论.