'django eventstream / channels return HTML
I have a working application where I use django-eventstream to show info/error messages to users. All works well with send_event():
send_event("mychan", "message", msg)
but what I actually want to do is send some html directly to the frontend because I use htmx. How can I make this work and circumvent the DjangoJSONEncoder used by django-eventstream?
send_event("mychan", "message", {"data": "<h1>tesst</h1>"})
leads to:
Edit: I am aware of the json_encode = False flag for send_event(), this products the same result:
send_event("mychan", "message", "<h1>tesst</h1>", json_encode = False)
leads to:
In the webdev console this looks as follows (this is the same as django's mark_safe() produces in a httpresponse object:
"<b>tesst</b>"
I don't want to clean away the double quotes with JS :)
Edit2: After some further digging I modified the source code of django-eventstream with a print() statement, that prints the event and the json_encode setting every time a message is sent to the frontend. With json_encode = False set, this leads to this output:
> event_type: message, data: <b>tesst</b>, json_encode: False
> event_type: message, data: <b>tesst</b>, json_encode: True
> event_type: message, data: <b>tesst</b>, json_encode: True
> event_type: message, data: <b>tesst</b>, json_encode: True
> event_type: message, data: <b>tesst</b>, json_encode: True
I wrapped send_event() in a wrapper function that does a print() whenever it is executed, and I only see one print but multile SSE events result - only the first one takes json_encode into account.
The very ugly hack to set json_encode = False in the source code of django-eventstream does work. But this seems like a very bad solution.
Solution 1:[1]
The send_event function has a json_encode option that you can set to False to prevent the encoding - that should fix your issue.
Solution 2:[2]
Django has mark_safe method, which works great for html in django admin table cells, which would normally remove html tags.
From the docs:
mark_safe(s)
Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string is appropriate.
Can be called multiple times on a single string.
Can also be used as a decorator.
For building up fragments of HTML, you should normally be using django.utils.html.format_html() instead.
I'm not sure about your case, but it's worth trying, as well as django.utils.html.format_html as stated above.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | user50806 |
| Solution 2 | nenadp |


