question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error "can't serialize <model instance>" when using channels_redis as channel layer

See original GitHub issue

When having following subscription code (MessageModel is a Django model class):

class Message(DjangoObjectType):
    class Meta:
        model = MessageModel

class MessageAddedSubscription(channels_graphql_ws.Subscription):
    Output = Message

    @staticmethod
    def publish(payload, info):
        return payload

and calling broadcast elsewhere like this:

new_message = MessageModel.objects.create(text='some text')
MessageAddedSubscription.broadcast(payload=new_message)

… application crashes because it’s unable to serialize the model instance to redis-backed channel layer:

An error occurred while resolving field Mutations.messageAdd
Traceback (most recent call last):
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphql/execution/executor.py", line 311, in resolve_or_error
    return executor.execute(resolve_fn, source, info, **args)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphql/execution/executors/sync.py", line 7, in execute
    return fn(*args, **kwargs)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphene_django/debug/middleware.py", line 56, in resolve
    promise = next(root, info, **args)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphql/execution/middleware.py", line 57, in make_it_promise
    return Promise.resolve(next(*a, **b))
  File "/Users/xaralis/Workspace/obs/obs-server/obs/schema.py", line 30, in mutate
    MessageAddedSubscription.broadcast(payload=new_message)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/channels_graphql_ws/graphql_ws.py", line 182, in broadcast
    'payload': payload})
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/asgiref/sync.py", line 64, in __call__
    return call_result.result()
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/_base.py", line 432, in result
    return self.__get_result()
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/asgiref/sync.py", line 78, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/channels_redis/core.py", line 317, in group_send
    self._map_channel_to_connection(channel_names, message)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/channels_redis/core.py", line 368, in _map_channel_to_connection
    channel_to_message[channel] = self.serialize(message)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/channels_redis/core.py", line 386, in serialize
    value = msgpack.packb(message, use_bin_type=True)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/msgpack/__init__.py", line 47, in packb
    return Packer(**kwargs).pack(o)
  File "msgpack/_packer.pyx", line 284, in msgpack._packer.Packer.pack
  File "msgpack/_packer.pyx", line 290, in msgpack._packer.Packer.pack
  File "msgpack/_packer.pyx", line 287, in msgpack._packer.Packer.pack
  File "msgpack/_packer.pyx", line 234, in msgpack._packer.Packer._pack
  File "msgpack/_packer.pyx", line 281, in msgpack._packer.Packer._pack
TypeError: can't serialize <Message: Message object (39)>
Traceback (most recent call last):
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphql/execution/executor.py", line 330, in complete_value_catching_error
    exe_context, return_type, field_asts, info, result)
  File "/Users/xaralis/.venvs/obs/lib/python3.6/site-packages/graphql/execution/executor.py", line 383, in complete_value
    raise GraphQLLocatedError(field_asts, original_error=result)
graphql.error.located_error.GraphQLLocatedError: can't serialize <Message: Message object (39)>

What is the recommended way to handle Django model instances? Thanks

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
bewestphalcommented, May 24, 2020

I wanted to make the message object the same as one from a query so it’s easier to manipulate in the client.

This had me stuck for a while, so leaving this for anyone that comes here from google.

Testing on django==3.0.6 graphene-django==2.10.1 django-channels-graphql-ws==0.5.0

class ChatSubscription(channels_graphql_ws.Subscription):
    """Subscription triggers on a new chat message."""

    message = graphene.Field(Message)
  
   # ....the rest of your subscription class

   def publish(message: MessageModel, info: ResolveInfo, **arguments):
       return ChatSubscription(message=message)

   @classmethod
    def new_message(cls, message: MessageModel):
        cls.broadcast(group=message.chat_id, payload=message)
0reactions
xaraliscommented, Aug 7, 2018

@prokher You’re awesome!

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeError: can not serialize 'User' object in Chat Application
I want to integrate a chat app with my ...
Read more >
Channels Documentation - Read the Docs
A channel layer is a kind of communication system. It allows multiple consumer instances to talk with each other, and with other parts...
Read more >
What's new in Channels 2? — Channels 2.4.0 documentation
If you are using Python 2, or a previous version of Python 3, you cannot use Channels 2 as it relies on the...
Read more >
Build a Chat App with Django Channels - JustDjango
Django Channels has what are called channel layers. ... Return the user model instance associated with the given scope.
Read more >
django-channels - Bountysource
Hello, I am trying to send a message to two different instances of my application with different layer names in one async function,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found