Action

Action is a concept of rest_framework_channels to handle the message. Action is similar with HTTP request method, moreover you can define the original action flexibly.

The client establishes the connection to the server using websocket, first. Once establishing the connection, you can send the messages with any actions. All actions will be handled by ActionHandler (detailed in next section) which is similar with Consumer. Thanks to ActionHandler, you can handle with all actions very easily.

Note

Note that all ActionHandlers in rest_framework_channels.handlers and Consumers in rest_framework_channels.consumers are inherited from AsyncActionHandler which is the base class of ActionHandler. Therefore, Consumer is also ActionHandler.

group channels
    Client -> Consumer: connect
    return accept
end

group rest_framework_channels
    Client -> Consumer: action

    Consumer -> ActionHandler: action
    return response

    Consumer -> Client: response
end

group channels
    Client -> Consumer: disconnect
    return close
end

Generics Action List

We are ready for generics ActionHandler (such like rest_framework’s generics view). Thanks to these generics, you can implement the codes handling with some actions very easily. And these generics interfaces are almost same as the rest_framework’s generics view. That’s why you can implement the websockets code easily!

Here is the generic action list corresponding to HTTP request method.

action

HTTP request

retrieve

GET

list

GET

create

POST

update

PUT

partial_update

PATCH

remove

DELETE

For more details in generics section.

Define your custom action

When you want to handle with your custom action, you can define the handler method warapped async_action decorator.

from rest_framework_channels.handlers import AsyncAPIActionHandler
from rest_framework_channels.decorators import async_action
from rest_framework_channels.consumers import AsyncAPIConsumer

class ChildActionHandler(AsyncAPIActionHandler):

    @async_action()
    def your_custom_action(self, pk, *args, **kwargs):
        # Note: you should return the data and status code.
        return { 
            'message': 'your_custom_action will be handled',
            'model_id': pk
        }, 200

class ParentConsumer(AsyncAPIConsumer):
    routepatterns = [
        re_path(
            r'test_child_route/(?P<pk>[-\w]+)/$',
            ChildActionHandler.as_aaah(),
        ),
    ]

After establishing the connection and sending the below json,

{
    'action': 'your_custom_action', # your method name will be action's name directly
    'route': 'test_child_route/5/'
}

the new model will be created and you will get the below response.

{
    'errors': [],
    'action': 'your_custom_action',
    'data': {
        'message': 'your_custom_action will be handled',
        'model_id': 5
    },
    'route': 'test_child_route/5/',
    'status': 200,
}

Important

As you can guess from the decorator’s name async_action, your decorated method will be converted into the ASYNC method. That’s why when you want to call this method in sync method, you should use async_to_sync in asgiref.

from asgiref.sync import async_to_sync

class ChildActionHandler(AsyncAPIActionHandler):
    permission_classes = (IsAuthenticated,)

    ...

    def your_sync_method(self, pk):
        data, status = async_to_sync(self.your_custom_action)(pk=pk)
        ...