[Fixed]-How can I make SSE with Python (Django)?


This is working example from w3schools in Django:


<!DOCTYPE html>

<h1>Getting server updates</h1>
<div id="result"></div>

if(typeof(EventSource) !== "undefined") {
  var source = new EventSource("stream/");
  source.onmessage = function(event) {
    document.getElementById("result").innerHTML += event.data + "<br>";
} else {
  document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";



import datetime
import time
from django.http import StreamingHttpResponse

def stream(request):
    def event_stream():
        while True:
            yield 'data: The server time is: %s\n\n' % datetime.datetime.now()
    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')


urlpatterns = [
    path('stream/', views.stream, name='stream')


If you want to manage your notifications you can create the model like:

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)

Then create the view that is looking for the first unsent notification and sends it:

def stream(request):
    def event_stream():
        while True:
            notification = Notification.objects.filter(
                sent=False, user=request.user

            text = ''

            if notification:
                text = notification.text
                notification.sent = True

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

    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')

And the send_notification function that creates an entry in the Notification model (just call this function from anywhere in your code):

def send_notification(user, text):
        user=user, text=text


After reading this, I think I understood the whole thing (please comment if I’m wrong).

Django does NOT natively support keep-alive connections. 
This means, when the client gets the message from the server, the connection is immediately closed after (like any classic HTTP request/response cycle).

What’s different with text/event-stream request, is that the client automatically tries to reconnect to the server every second (the length can be changed with a retry parameter).

Unfortunately, it seems using SSE in that case has no interest since it has the same con’s that polling (ie. a request/response cycle occurs each X seconds).

As expected and mentioned in other answers, I would need django-channels to create a persistent connection that prevent HTTP request/response overheads and ensure the message is sent immediately.


As mentioned in other answers, you will need to use Django Channels to properly handle asynchronous communication without tying up threads.

For an example, see the django-eventstream library which uses Channels to implement SSE.

Leave a comment