帮助使用通道在websockets之上构建restful api。

channels_api的Python项目详细描述


通道API

https://travis-ci.org/linuxlewis/channels-api.svg?branch=master

channels api使用 频道。它提供了一个与django相当的ResourceBinding。 rest框架的ModelViewSet。它基于drf序列化程序 上课。

它需要python 2.7或3.x、channels<;=1.1.8.1、django<;=1.11和django rest framework 3.x

从我在SF Django MeetupPyBay 2016的演讲中,您可以了解有关channels api的更多信息

它是如何工作的?

api构建在通道WebsocketBinding类之上。它的工作原理是 客户端发送一个streampayload参数。这允许 我们将消息路由到特定的不同流(或资源) 行动。因此POST /user将有一条如下所示的消息

varmsg={stream:"users",payload:{action:"create",data:{email:"test@example.com",password:"password"}}}ws.send(JSON.stringify(msg))

为什么?

您已经在使用django rest框架,并希望公开类似的 基于websockets的逻辑。

websockets可以向客户端发布更新而无需请求。这是 当一个资源可以被跨多个平台的多个用户编辑时非常有用。

开始

本教程假设您熟悉频道并已完成 Getting Started

  • channels_api添加到requirements.txt
pip install channels_api
  • channels_api添加到INSTALLED_APPS
INSTALLED_APPS=('rest_framework','channels','channels_api')
  • 添加第一个资源绑定
# polls/bindings.pyfromchannels_api.bindingsimportResourceBindingfrom.modelsimportQuestionfrom.serializersimportQuestionSerializerclassQuestionBinding(ResourceBinding):model=Questionstream="questions"serializer_class=QuestionSerializerqueryset=Question.objects.all()
  • WebsocketDemultiplexer添加到channel_routing
# proj/routing.pyfromchannels.generic.websocketsimportWebsocketDemultiplexerfromchannels.routingimportroute_classfrompolls.bindingsimportQuestionBindingclassAPIDemultiplexer(WebsocketDemultiplexer):consumers={'questions':QuestionBinding.consumer}channel_routing=[route_class(APIDemultiplexer)]

就这样。现在可以向服务器发出rest websocket请求。

varws=newWebSocket("ws://"+window.location.host+"/")ws.onmessage=function(e){console.log(e.data)}varmsg={stream:"questions",payload:{action:"create",data:{question_text:"What is your favorite python package?"},request_id:"some-guid"}}ws.send(JSON.stringify(msg))// response
{stream:"questions",payload:{action:"create",data:{id:"1",question_text:"What is your favorite python package"}errors:[],response_status:200request_id:"some-guid"}}
  • 添加频道调试器页(可选)

此页有助于调试来自浏览器的API请求,并查看 回应。它只在DEBUG=TRUE时使用。

# proj/urls.pyfromdjango.conf.urlsimportincludeurlpatterns=[url(r'^channels-api/',include('channels_api.urls'))]

资源绑定

默认情况下,ResourceBinding实现以下rest方法:

  • create
  • retrieve
  • update
  • list
  • delete
  • subscribe

有关每个方法的使用示例,请参见测试套件。

列表分页

分页由django.core.paginator.paginator处理

您可以通过重写设置来配置DEFAULT_PAGE_SIZE

# settings.pyCHANNELS_API={'DEFAULT_PAGE_SIZE':25}

订阅

订阅是以编程方式接收更新的一种方式 每当创建、更新或删除资源时,从服务器

默认情况下,channels api实现了以下订阅

  • 创建资源
  • 更新任何资源
  • 更新此资源
  • 删除任何资源
  • 删除此资源

要订阅特定事件,只需使用subscribe操作 使用要筛选的参数

// get an event when any question is updated
varmsg={stream:"questions",payload:{action:"subscribe",data:{action:"update"}}}// get an event when question(1) is updated
varmsg={stream:"questions",payload:{action:"subscribe",pk:"1",data:{action:"update"}}}

自定义操作

要添加自己的自定义操作,请使用detail_actionlist_action 装饰师。

fromchannels_api.bindingsimportResourceBindingfromchannels_api.decoratorsimportdetail_action,list_actionfrom.modelsimportQuestionfrom.serializersimportQuestionSerializerclassQuestionBinding(ResourceBinding):model=Questionstream="questions"serializer_class=QuestionSerializerqueryset=Question.objects.all()@detail_action()defpublish(self,pk,data=None,**kwargs):instance=self.get_object(pk)result=instance.publish()returnresult,200@list_action()defreport(self,data=None,**kwargs):report=self.get_queryset().build_report()returnreport,200

然后在消息中将方法名作为“action”传递

// run the publish() custom action on Question 1
varmsg={stream:"questions",payload:{action:"publish",data:{pk:"1"}}}// run the report() custom action on all Questions
varmsg={stream:"questions",payload:{action:"report"}}

权限

channels api提供了一个受rest_框架启发的简单的权限类系统。 提供了两个权限类:AllowAnyIsAuthenticated

要全局配置权限,请使用设置DEFAULT_PERMISSION_CLASSES,如下所示

# settings.pyCHANNELS_API={'DEFAULT_PERMISSION_CLASSES':('channels_api.permissions.AllowAny',)}

您还可以像这样在ResourceBinding本身上配置权限类

fromchannels_api.permissionsimportIsAuthenticatedclassMyBinding(ResourceBinding):permission_classes=(IsAuthenticated,)

最后,要实现自己的权限类,请重写BasePermissionhas_permission

fromchannels_api.permissionsimportBasePermissionclassMyPermission(BasePermission):defhas_permission(self,user,action,pk):ifaction=="CREATE":returnTruereturnFalse

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
具有多用户OU和多访问CNs的java Spring LDAP身份验证   java分配的变量神秘地变为null   java比较两个表或文本文件,并用行号和列输出差异   java如何在同一构建目录中设置netbeans中的文件路径?   java如何在avro模式中定义byte[]和LocalDateTime?   java在多个活动和片段中使用相同的微调器。实施它的最佳方式是什么?   java使用OOPS扩展已编写的类   java如何在特定于文件的基础上禁用Eclipse中的编译器警告?   java将字符串转换为日期的格式不正确   Java文件从一台服务器复制到另一台服务器   java Jacksonal和JacksonApperasl的最新jar版本是什么?   java如何在使用selenium chrome web驱动程序时禁用chrome中的身份验证提示   java是什么。推荐人和推荐人。Eclipse工作区中的元数据以及它们是否应该在设备之间同步?   java我应该把sqlite db文件放在哪里,这样我的jar就可以访问它了?这对连接字符串有何影响?   java如何在选择单元格时设置JTable标题背景色   java Cassandra 2 Hector:复合行键上的范围切片查询返回空行   java方法注释继承   Python字节对象与java   java Android和从sqlite数据库加载listview