django / channels

Developer-friendly asynchrony for Django

Home Page:https://channels.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature Request: Add `add_to_group` function to Consumers

christophertubbs opened this issue · comments

Consumer classes seem to rely on the self.channel_layer.group_add function to register themselves to different groups. I'm not sure of the use cases for requiring the caller to specify the consumer's channel_name directly, but I'm sure it's just a blind spot for me. For an entry level user like me, though, the following function would help remove room for error and serve as a good quality of life improvement:

class AsyncConsumer:
    async def add_to_group(self, group_name: str):
        """
        Function used to demystify how group addition to work.

        self.channel_layer.group_add(<group_name>, self.channel_name) should generally be called like that. The only
        variation should be the group name.

        Args:
            group_name: The name of the group that this instance of this consumer should belong to
        """
        await self.channel_layer.group_add(group_name, self.channel_name)

This would simplify some of the example code to look like

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        room_name = self.scope["url_route"]["kwargs"]["room_name"]
        group_name = "chat_%s" % self.room_name

        # Join room group
        await self.add_to_group(group_name)

        await self.accept()

instead of

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
        self.room_group_name = "chat_%s" % self.room_name

        # Join room group
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)

        await self.accept()

It doesn't seem like a lot, but it reduces cognitive complexity.

You're welcome to add such a method to your own consumers but it's not something we'd add to the public API. (There's already one way to do it.)