如何使用Python(Django)制作SSE?

如何使用Python(Django)制作SSE?,python,django,django-models,server-sent-events,Python,Django,Django Models,Server Sent Events,我有两个不同的页面,一个(A)显示从模型对象获取的数据,另一个(B)更改其字段。 我希望当post数据从B发送到服务器时,服务器会更改A中的值。 最好的方法是什么 这个例子可以为我工作,但它是在PHP。。。有一种方法可以用Python复制它吗? 这是Django w3schools的工作示例: 模板 网址 更新: 如果要管理通知,可以创建如下模型: from django.db import models class Notification(models.Model): text =

我有两个不同的页面,一个(A)显示从模型对象获取的数据,另一个(B)更改其字段。 我希望当post数据从B发送到服务器时,服务器会更改A中的值。 最好的方法是什么

这个例子可以为我工作,但它是在PHP。。。有一种方法可以用Python复制它吗?
这是Django w3schools的工作示例:

模板

网址

更新:

如果要管理通知,可以创建如下模型:

from django.db import models

class Notification(models.Model):
    text = models.CharField(max_length=200)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sent = models.BooleanField(default=False)
然后创建查找第一个未发送通知的视图并发送该通知:

@login_required
def stream(request):
    def event_stream():
        while True:
            time.sleep(3)
            notification = Notification.objects.filter(
                sent=False, user=request.user
            ).first()

            text = ''

            if notification:
                text = notification.text
                notification.sent = True
                notification.save()

            yield 'data: %s\n\n' % text

    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')
以及
send_notification
函数,该函数在
notification
模型中创建一个条目(只需在代码中的任意位置调用此函数):

就这么简单。

读完后,我想我明白了整个事情(如果我错了,请评论)。



Django本机不支持保持活动连接。
这意味着,当客户端从服务器获取消息时,连接会在之后立即关闭(就像任何经典的HTTP请求/响应周期一样)


与
文本/事件流
请求不同的是,客户端每秒自动尝试重新连接到服务器(长度可以通过
重试
参数更改)。



不幸的是,在这种情况下使用SSE似乎没有什么意义,因为它具有与轮询相同的con(即每X秒发生一次请求/响应周期)




正如在其他答案中所预期和提到的,我需要django通道来创建持久连接,以防止HTTP请求/响应开销,并确保消息立即发送。


如其他答案中所述,您需要使用Django通道来正确处理异步通信,而不会占用线程


例如,请查看哪个使用通道来实现SSE。

选中?它可以正常工作,但行为不是我所期望的。页面会随着新服务器时间不断更新。如果我想向我的客户发送一个特定的(仅一次)事件,该怎么办?嗨@Ivan,谢谢你的更新。我在了解到SSE不能像预期的那样与Django一起工作后发布了我的答案,因为它不支持持久连接:(值得一提的是,
StreamingHttpResponse
价格昂贵,应该避免。在Django 3.1支持异步视图的情况下,这些关于性能和持久连接的评论是否仍然相关主要的好处是能够在不使用Python线程的情况下为数百个连接提供服务。这允许您使用慢速流、长轮询和其他令人兴奋的响应类型
urlpatterns = [
    path('stream/', views.stream, name='stream')
]
from django.db import models

class Notification(models.Model):
    text = models.CharField(max_length=200)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sent = models.BooleanField(default=False)
@login_required
def stream(request):
    def event_stream():
        while True:
            time.sleep(3)
            notification = Notification.objects.filter(
                sent=False, user=request.user
            ).first()

            text = ''

            if notification:
                text = notification.text
                notification.sent = True
                notification.save()

            yield 'data: %s\n\n' % text

    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')
def send_notification(user, text):
    Notification.objects.create(
        user=user, text=text
    )