Chandler Bing
Chandler Bing

Reputation: 97

How do I use Django channels to open a Websocket for Django Rest Api?

https://github.com/prateekamana/tempstack

So I have a simple app where I want to fetch articles in my react fronted without having to refresh the page dynamically. I know for that I either have to implement websockets or sse connection. So I tried to implement that using Django channels but I can't figure out how to set it up.

I installed channels but everywhere the examples are for a chat application, I just want to simply fetch articles with the websocket from my rest api. Could you please tell me how do I route the websockets without the AuthMiddlewareStack() ? (Because I gather that has to do something with user authentication which I don't want to deal with as it is not a chat app.)

    # WebSocket chat handler
    "websocket": AuthMiddlewareStack(
        URLRouter([
            url(r"^chat/admin/$", AdminChatConsumer),
            url(r"^chat/$", PublicChatConsumer),
        ])
    ),

    # Using the third-party project frequensgi, which provides an APRS protocol
    "aprs": APRSNewsConsumer,

})```

Upvotes: 0

Views: 3368

Answers (1)

Matthaus Woolard
Matthaus Woolard

Reputation: 2408

I suggest looking at using https://github.com/hishnash/djangochannelsrestframework this package. https://lostmoa.com/blog/DjangoChannelsRestFramework/ is an arcile that goes into exposing a rest api over your websocket using this.

However you can also use the above package to address your existing Django views.

application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter([
            url(r"^front(end)/$", view_as_consumer(YourDjangoView)),
        ])
    ),
 })

I would suggest since it is likely that you will want to load more than one object type over your websocket connection that you look into using this alongside: https://github.com/hishnash/channelsmultiplexer

this will let you multiplex messages through a single websocket connection to multiple consumers.

class DemultiplexerAsyncJson(AsyncJsonWebsocketDemultiplexer):
    applications = {
        "users": view_as_consumer(UserDjangoView),
        "classrooms": ClassroomConsumer,
        # ....
    }

application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter([
            url(r"^ws/$", DemultiplexerAsyncJson),
        ])
    ),
 })

Then your frontend can send messages over the same websocket connection

For example to get all users from the UserDjangoView you can send.

{
    "stream": "users",
    "payload": {"action": "delete", "pk": 42}
}

For more granular control over your rest api consumers consider using the GenericAsyncAPIConsumer class.


Disclaimer I am the maintainer of the above packages.

Upvotes: 3

Related Questions