[Django]-Remove a specific user from a Django Channels group?

-1๐Ÿ‘

โœ…

I solved this in the end by storing each channel name (self.channel_name) on channel connection, and removing them on disconnect. These are then tied to a Django user object.

Now, if I want to remove a user from a group, I can just loop over all stored channel names tied to a user object, and run group_discard.

๐Ÿ‘คJames Foley

4๐Ÿ‘

First, you have to save the userโ€™s channel_name to their model

and we assume that you had the group_name of channels too

then you can use group_discard for deleting user from group like this:

group_name = 'name_of_channels_group'
user = User.objects.get(id=id)
channel_name = user.channel_name
async_to_sync(self.channel_layer.group_discard)(group_name, channel_name)

https://channels.readthedocs.io/en/stable/topics/channel_layers.html?highlight=group_send#groups

๐Ÿ‘คAli Rn

0๐Ÿ‘

I have thought couple a days about this problem and have an idea how this can be implemented, but canโ€™t test it currently. You should try to change your receive() method like this:

async def receive(self, text_data=None, bytes_data=None):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        users_to_kick = text_data_json['kick']

        # you should inspect scope['user'] cuz I am not sure in what place
        # user's id is placed, but there is 'user' object.
        if self.scope['user']['id'] in list(map(int, users_to_kick)):
            await self.close()
        else:
            await self.channel_layer.group_send(
                self.room_group_name,
                {
                    'type': 'some_method',
                    'message': message
                 }
             )

You have to have Authorisation system enabled, you canโ€™t kick Anonymous users. And you have to send from Front-End a list of users which you want to kick.

๐Ÿ‘คChiefir

-1๐Ÿ‘

You need to prevent connect based on scope['user'] in consumer connect method like this:

class MyConsumer(AsyncJsonWebsocketConsumer):

    async def connect(self):
        id_cannot_connect = 1
        if self.scope['user'] == id_cannot_connect:
            await self.close()
        else:
            await self.accept()

If you want to make lists of users allowed to connect to specific groups youโ€™ll need to store groups and group users in your database and use it the same way in connect method like above.

edit: You can discard userโ€™s channel from the group with group_discard in receive_json where you still have access to self.scope['user'] to filter needed users.

Leave a comment