gpt4 book ai didi

python - 实时动态更新 django 模板

转载 作者:行者123 更新时间:2023-12-04 12:04:10 27 4
gpt4 key购买 nike

我正在构建一个将提供实时数据的 django 应用程序。我对 Django 相当陌生,现在我专注于如何实时更新我的​​数据,而不必重新加载整个页面。

一些澄清:实时数据应该定期更新,而不仅仅是通过用户输入。

查看

def home(request):

symbol = "BTCUSDT"
tst = client.get_ticker(symbol=symbol)

test = tst['lastPrice']

context={"test":test}

return render(request,
"main/home.html", context
)

模板
<h3> var: {{test}} </h3>

我已经问过这个问题,但我有一些疑问:

有人告诉我使用 Ajax,这没问题,但是 Ajax 是否适合这种情况,我将每 x 秒加载一个包含实时更新数据的页面?

我还被告知使用 DRF(Django Rest Framework)。我一直在深入研究它,但我不清楚它是如何处理这个特殊情况的。

最佳答案

在下面,我给出了实现基于 Websocket 和 Django Channels 的解决方案所需的操作 list ,如之前的评论中所建议的。
最后给出了这样做的动机。

1)连接Websocket,准备接收消息

在客户端,您需要执行以下 javascript 代码:

<script language="javascript">
var ws_url = 'ws://' + window.location.host + '/ws/ticks/';
var ticksSocket = new WebSocket(ws_url);

ticksSocket.onmessage = function(event) {
var data = JSON.parse(event.data);
console.log('data', data);
// do whatever required with received data ...
};
</script>

这里,我们打开Websocket,后面在 onmessage中详细说明服务器发送的通知打回来。

可能的改进:
  • 支持 SSL 连接
  • 使用 ReconnectingWebSocket:WebSocket API 上的一个小包装器,可自动重新连接
  •     <script language="javascript">
    var prefix = (window.location.protocol == 'https:') ? 'wss://' : 'ws://';
    var ws_url = prefix + window.location.host + '/ws/ticks/';
    var ticksSocket = new ReconnectingWebSocket(ws_url);
    ...
    </script>

    2) 安装和配置 Django Channels 和 Channel Layers

    要配置 Django channel ,请按照以下说明操作:

    https://channels.readthedocs.io/en/latest/installation.html

    Channel Layers 是 Django Channels 的一个可选组件,它提供了一个我们稍后将使用的“组”抽象;您可以按照此处给出的说明进行操作:

    https://channels.readthedocs.io/en/latest/topics/channel_layers.html#

    3)发布Websocket端点

    路由为 Websocket(和其他协议(protocol))提供了已发布端点和相关服务器端代码之间的映射,就像 urlpattens 在传统 Django 项目中为 HTTP 所做的那样

    文件 routing.py
    from django.urls import path
    from channels.routing import ProtocolTypeRouter, URLRouter
    from . import consumers

    application = ProtocolTypeRouter({
    "websocket": URLRouter([
    path("ws/ticks/", consumers.TicksSyncConsumer),
    ]),
    })

    4)写入消费者

    Consumer 是一个为 Websocket 标准(也可能是自定义)事件提供处理程序的类。从某种意义上说,它对 Websocket 的作用就像 Django View 对 HTTP 所做的那样。

    在我们的例子中:
  • websocket_connect():我们接受连接并将传入的客户端注册到“ticks”组
  • websocket_disconnect():通过从组中删除 che 客户端进行清理
  • new_ticks():我们的自定义处理程序,它将接收到的滴答广播到它的 Websocket 客户端
  • 我假设 TICKS_GROUP_NAME 是在项目设置中定义的常量字符串值

  • 文件 consumers.py :
    from django.conf import settings
    from asgiref.sync import async_to_sync
    from channels.consumer import SyncConsumer

    class TicksSyncConsumer(SyncConsumer):

    def websocket_connect(self, event):
    self.send({
    'type': 'websocket.accept'
    })

    # Join ticks group
    async_to_sync(self.channel_layer.group_add)(
    settings.TICKS_GROUP_NAME,
    self.channel_name
    )

    def websocket_disconnect(self, event):
    # Leave ticks group
    async_to_sync(self.channel_layer.group_discard)(
    settings.TICKS_GROUP_NAME,
    self.channel_name
    )

    def new_ticks(self, event):
    self.send({
    'type': 'websocket.send',
    'text': event['content'],
    })

    5)最后:广播新的滴答声

    例如:
    ticks = [
    {'symbol': 'BTCUSDT', 'lastPrice': 1234, ...},
    ...
    ]
    broadcast_ticks(ticks)

    在哪里:
    import json
    from asgiref.sync import async_to_sync
    import channels.layers

    def broadcast_ticks(ticks):
    channel_layer = channels.layers.get_channel_layer()
    async_to_sync(channel_layer.group_send)(
    settings.TICKS_GROUP_NAME, {
    "type": 'new_ticks',
    "content": json.dumps(ticks),
    })

    我们需要附上对 group_send() 的调用在 async_to_sync()包装器,因为 channel.layers 只提供异步实现,我们从同步上下文调用它。 Django Channels 文档中提供了更多详细信息。

    笔记:
  • 确保“type”属性与消费者处理程序的名称匹配(即:'new_ticks');这是必需的
  • 每个客户都有自己的消费者;所以当我们在消费者的处理程序中编写 self.send() 时,这意味着:将数据发送到单个客户端
  • 在这里,我们将数据发送到“组”抽象,然后 channel 层将把它传递给每个注册的消费者

  • 动机

    在某些情况下,轮询仍然是最合适的选择,简单而有效。

    但是,在某些情况下,您可能会遇到一些限制:
  • 即使没有新数据可用,您也会继续查询服务器
  • 你引入了一些延迟(在最坏的情况下,轮询的整个时期)。权衡是:更少的延迟 = 更多的流量。

  • 使用 Websocket,您可以改为仅在有新数据可用时(以及尽快)通过向客户端发送特定消息来通知客户端。

    关于python - 实时动态更新 django 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56913676/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com