Hello All,
Trying to work out this issue with a chat website built with Django, Channels, and HTMX over an AsyncWebsocketConsumer.
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope["user"]
self.user_phone_num = self.scope['url_route']['kwargs']['user_phone_num']
self.room_group_name = 'chat_%s' % self.user_phone_num
user_phone_num_obj = await UserPhone.objects.aget(phone=self.user_phone_num)
conv_obj = await Conversation.objects.aget(phonenumber=user_phone_num_obj)
redis_online_name = self.room_group_name + '_online'
await redis_instance.sadd(redis_online_name, self.user.first_name + ' ' + self.user.last_name)
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
context = {
"online_users": redis_instance.smembers(redis_online_name)
}
rendered_html = render_to_string("partials/message/hx_online_users.html", context)
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'online_users_list',
'html': rendered_html,
}
)
await self.accept()
My code renders the error:
2023-03-27 01:49:45,008 server ERROR Exception inside application: 'coroutine' object is not iterable
Traceback (most recent call last):
File "/...//venv/lib/python3.11/site-packages/channels/routing.py", line 62, in __call__
return await application(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/sessions.py", line 263, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/auth.py", line 185, in __call__
return await super().__call__(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/middleware.py", line 24, in __call__
return await self.inner(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/routing.py", line 116, in __call__
return await application(
^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/consumer.py", line 94, in app
return await consumer(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/channels/consumer.py", line 58, in __call__
await await_many_dispatch(
File "/...//venv/lib/python3.11/site-packages/channels/utils.py", line 50, in await_many_dispatch
await dispatch(result)
File "/...//venv/lib/python3.11/site-packages/channels/consumer.py", line 73, in dispatch
await handler(message)
File "/...//venv/lib/python3.11/site-packages/channels/generic/websocket.py", line 173, in websocket_connect
await self.connect()
File "/...//chat/consumers.py", line 68, in connect
rendered_html = render_to_string("partials/message/hx_online_users.html", context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/base.py", line 175, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/test/utils.py", line 111, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/...//venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 193, in render
values = list(values)
^^^^^^^^^^^^
TypeError: 'coroutine' object is not iterable
I understand my issue must be related to the fact that rendering templates is synchronous - however I have attempted to use the sync_to_async function and await, but I am met with the same error.
How can I render the template from an async function?