Django - 通过 websocket 在事件上重复发送 API 调用结果(REST 框架 + 通道)

Posted

技术标签:

【中文标题】Django - 通过 websocket 在事件上重复发送 API 调用结果(REST 框架 + 通道)【英文标题】:Django - repeatedly send API call result via websocket on events (REST Framework + Channels) 【发布时间】:2020-10-13 20:05:49 【问题描述】:

我在将 Django REST Framework 与 Django Channels 集成时遇到了一个问题。

我有一个带有retrieve (GET) 方法的视图集,它以棘手的方式准备来自几个不同模型的信息,并将这个“复杂”结果发送到前端。因此,当客户端向此端点(如/complex_entity/1)发送带有实体主键的 GET 请求时,他会立即收到他需要的一切。

现在前端的人想要拥有另一个功能 - 每次更改一些相关的底层模型时,后端应该能够将这个复杂请求的结果发送到前端。像这样:浏览器使用主键1 订阅ComplexEntity 的更改,并且当ComplexEntity 1 更改(或其链接实体不是问题)时,服务器通过websocket 发送这个复杂请求的结果。因此请求可以在一个 websocket 连接期间执行多次(在每个模型更改信号上)。

我看到了提供这种行为的两种直观方法:(?):以某种方式从 django 本身执行对此视图集 retrieve 方法的请求 - 通过内部调用此方法或通过执行“环回”HTTP 请求。Bad/ugly:将所有复杂逻辑从视图集 retrieve 方法复制到 websocket 消费者

另外我发现Django Channels REST Framework 允许订阅模型实体,但问题是我不仅需要返回模型实例,还需要返回从多个模型粘合的“自定义”结果。据我了解,DCRF 缺少该功能。

现在我真的不知道解决我的问题的最佳方法是什么 - 看起来内部调用方法是可以的,但该怎么做? 环回 HTTP 请求也可以(我认为),但它应该与站点主机名解开,理智表示最好将“发起者”cookie 转发到此类请求,以防止未经授权访问实体。问题是,如何正确地做到这一点。

那么有谁知道在一个 websocket 连接期间多次执行相同复杂请求的最佳方法是什么?

【问题讨论】:

【参考方案1】:

正确的方法是将通用逻辑移动到可重用的方法中,并在 DRF 视图和通道中使用它。

该方法将接收一些参数(我猜是ComplexEntity 的 ID)并以您需要的格式返回结果数据。

【讨论】:

感谢您的好主意!我什至没有想过将任何代码移动到“共享”文件,因为我真的习惯认为 Django 中的任何代码段都有一个众所周知的特定文件,除了它是一个无礼的垃圾:)跨度>

以上是关于Django - 通过 websocket 在事件上重复发送 API 调用结果(REST 框架 + 通道)的主要内容,如果未能解决你的问题,请参考以下文章

用于 django 应用程序的 websocket 服务器

Django:通过 websocket 定期发送更新

如何通过 Django 通道 WebSocket 传递请求并调用 Django 视图

通过 Django Channels 和 Websockets 向客户端推送实时更新

带有 websocket 的 Django 框架

django使用websocket