xtlc
xtlc

Reputation: 1378

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:

enter image description here

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:

enter image description here

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.

Upvotes: 0

Views: 960

Answers (2)

nenadp
nenadp

Reputation: 816

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.

Upvotes: 0

user50806
user50806

Reputation: 11

The send_event function has a json_encode option that you can set to False to prevent the encoding - that should fix your issue.

Code: https://github.com/fanout/django-eventstream/blob/b52c7e494afa93ada9abc36b86c724d90f5690b9/django_eventstream/eventstream.py#L14

Upvotes: 1

Related Questions