Search code examples
pythondjangowebsocketdjango-rest-frameworkdjango-channels

Django - repeatedly send API call result via websocket on events (REST Framework + Channels)


I came with a problem while integrating Django REST Framework with Django Channels.

I have a viewset with retrieve (GET) method that prepares information from several different models in tricky way and sends this "complex" result to the frontend. So when client sends GET request with entity primary key to this endpoint (like /complex_entity/1) he instantly receives everything he needed.

And now guys on the frontend side want to have another feature - backend should be able to send results of this complex request to the frontend each time when some of relevant underlying models were changed. Like this: browser subscribes for the changes of ComplexEntity with primary key 1 and when ComplexEntity 1 is changed (or its linked entities which is not a problem) server sends the result of this complex request via websocket. So the request can be executed many times during one websocket connection (on each model change signal).

I see two intuitive ways to provide this behaviour:
Good(?): somehow execute requests to this viewset retrieve method from the django itself - either by calling this method internally or by executing "loopback" HTTP request.
Bad/ugly: copy all complex logic from viewset retrieve method to websocket consumer

Also I've found Django Channels REST Framework which allows to subscribe to model entity but the problem is I need to return not just model instance but this "custom" result glued from several models. DCRF lacks that feature as I understood.

For now I don't really know what is the best way to solve my problem - looks like calling method internally is ok but how to do it?
Loopback HTTP request is ok too (I think) but it should be untied from site hostname and sanity says that it's better to forward "originator" cookies to such request to prevent unauthorized access to entities. The question is, again, how to do it right.

So does anybody know what is a best way to execute same complex request several times during one websocket connection?


Solution

  • The proper way would be to move the common logic into a reusable method and use it in both DRF view and in channels.

    That method will receive some arguments (I guess ComplexEntity's ID) and will return the result data in the format you need.