转自:http://www.360doc.com/content/13/0226/17/9342056_268046626.shtml
Django一款是Python的强大web开发框架, 由于它是url配置式的框架, 感觉上用它做RESTful的webservice应该是得心应手的。
果然我在探寻之下, 发现一款优秀的基于Django的轻量级RESTful api搭建框架: Piston。官方网址:https://bitbucket.org/jespern/django-piston/
基本上这货有这些主要功能:
- 直接链接Django内部auth机制(BasicAuth)
- 内置OAuth认证的实现,能快速使用
- 可绑定Model也可直接使用任意资源(任意Object)
- 支持JSON,YAML,Python Pickle, XML等各种数据格式,还可以自己扩展
- 提供Form验证和请求限制等实现
工作之余,写几篇文章介绍下这个东西之
Piston的RESTful实现
REST是Representational State Transfer (表述性状态转移)的缩写, 是一种轻量级的WebService架构比SOAP和XML-RPC简洁多了. REST架构遵循了CRUD原则, 即对于资源使用的四种行为: Create(创建), Read(读取), Update(更新), Delete(删除).
在Piston中, 我们需要写的就是对于资源(封装为piston.resource.Resouce, 在url配置中会使用)的操作类,即 Handler 类(全都继承与piston.handler.BaseHandler). 举个简单的例子好了
先在工程目录里加个api模块, 然后用这个结构就可以了
api/
__init__.py
urls.py
handlers.py
在handlers.py里简单写个Handler类来说明下Piston的结构:
class EntryHandler(BaseHandler):
model = TestModel
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
fields = ('title', 'content', ('author', ('username', 'first_name')),'author_count')
exclude = ('id', re.compile('^private_'))
def create(self, request):
...
def read(self, request, pk=None):
...
def update(self, request, pk):
...
def delete(self, request, pk):
...
@classmethod
def author_count(cls, m):
...
我们可以看到CRUD中的四个方法灰常直接了当得呈现出来了, REST的四个方法分别对应于:
- 当收到GET请求时, 调用read方法, 读取并返回资源,不做修改
- 当收到POST请求时, 调用create方法, 创建新的资源, 并返回(或返回内建的rc.CREATED)
- 当收到PUT请求时, 调用update方法, 更新现有资源, 并返回(或返回内建的rc.ALL_OK)
- 当收到DELETE请求时,调用delete方法, 删除现有资源, 只返回rc.DELETED
写了几个Handler类之后, 简单得小结一下几点:
- 属性model不是必须的, 但是如果设了model后,该Handler将自动和Django的模型绑定
- 如果settings中不设置PISTON_IGNORE_DUPE_MODELS为True,则一个model只能绑定一个BaseHandler和一个AnonymousBaseHandler, 不能同时绑定两个及以上BaseHandler
- 当model绑定后, BaseHandler中就实现了对该模型默认的以上4种操作. 不进行重写方法的话,这四种操作都能正常进行(前提是request中传来的必须是正确的Model序列化后的数据,否则将报错)
- 重写CRUD方法可以实现各种自定义操作, 如果不绑定Model, 那必须重写CRUD, 因为BaseHandler中的CRUD方法都是基于绑定模型的
- Handler是可以添加任意自定义函数的, 但是自定义函数必须加上@classmethod 装饰器, 因为自定义函数唯一的用途就是在field中使用(下面会介绍), 它能获得的只有两个参数,一个是Handler的类, 另一个Model的对象
- 我们可以在属性allowed_method中设置, 该handler类可以接受哪些请求
- exclude属性: 可以剔除返回的数据中, Model里的哪些Field是不需要的, 可以使用正则表达式来剔除
- field属性: 这个和exclude相反, 似乎优先级更高, 而且它还可以内联, 和使用自定义函数
- 内联可以联的是外键或者多对多关系
- 内联的方法是在field里加入一个Tuple, 如(‘author’, (‘username’, ‘first_name’))
其中author是外键或多对多关系的引用名,后面则是author中显示的内容 - 内联的层级是可以N层的
- field中可以使用自定函数的结果, 即Handler中自定义的函数
具体详细例子, 可以看Piston中的Test=-=
Piston的url配置和使用
上一节是说怎么写一个Handler类, 这里就是使用这个Handler类。 用过Django都知道url配置的重要=-=
Piston的url配制方法其实很简单,只要将Handler封装一下,然后加上认证的部分就可以了。简单的urls.py配置的例子:
_auth = HttpBasicAuthentication(realm='Test')
_AUTHENTICATORS = [_auth,]
_entries = Resource(handler=EntryHandler, authentication=_AUTHENTICATORS)
urlpatterns = patterns('',
url(r'^entries/$', _entries),
)
首先是要有个认证, 这边使用了Piston的HttpBasicAuthentication, 其实这个BasicAuth的账户验证是直接使用了Django自带的auth系统, 认证字符串则是自己的. 这个认证就是将认证字符串写在请求Meta中的HTTP_AUTHORIZATION字段上. 字符的格式是:
'Basic %s' % base64.encodestring('admin:admin').rstrip()
Basic+空格+base64后的”用户名:密码” ,如果格式不同就会认证不通过.认证时其实就是decode出用户名密码后调用Django的auth系统进行验证. 当然这个 Authentication是可以自定义的,可以参考HttpBasicAuthentication改写成任意的认证形式.
同时Piston是支持多认证机制的 只要在_AUTHENTIATORS数组中添加任意个Authenticator就可以实现多种认证机制同时存在
在认证器配置好后,只要用Resource类封装一下Handler和authentiators就可以了. 还有一点就是如果不需要认证的话, 不用添加Authenticator, 只要设置Handler即可. 是否需要认证和Handler是否继承与AnonymousBaseHandler无关, 它只是提供绑定Model的选择.
当请求通过认证后, 就去根据请求类型去到Handler类中的CRUD方法, 这是只要访问request.user即可获得认证后的user信息
url配置也很常规,不多阐述了. 回头说Emitter的时候再具体说一下url配置中的细节.
下一章, 我会说说怎么使用Piston来搭建OAuth认证机制, 还有就是Piston API的传输数据格式(关于Emitter)的问题 ~.~
http://baike.baidu.com/view/962167.htm