I have project on Django wich use Django Channels. I use Django Channel for sending notifications to users who are subscribed to articles changes (adding/editing/deleting comments on article).
So I've chosen this way of realization: every group of channels is an article and when changes happen, script sends notification to relevant groups. My code works correctly but I have some doubts if my choice of way of realization is most appropriate for this task. I need advice what is the best practice in my case?
Solution:
consumers.py
from channels.generic.websocket import AsyncJsonWebsocketConsumerfrom channels.db import database_sync_to_asyncfrom project.apps.account.models import UserStatusfrom .models import CommentSubscribeclass CommentNotificationConsumer(AsyncJsonWebsocketConsumer): async def connect(self): await self.accept() if not self.scope['user'].is_anonymous: groups = await database_sync_to_async(self.get_users_subscription)() await database_sync_to_async(self.change_user_status)(True) await self.add_subscriptions(groups) async def add_subscriptions(self, groups): for group in groups: await self.channel_layer.group_add( 'article_{0}'.format(group.article_id), self.channel_name ) async def receive_json(self, content, **kwargs): command = content.get('command', None) article_id = content.get('article_id', None) if command == 'subscribe': await self.subscribe(article_id) elif command == 'unsubscribe': await self.unsubscribe(article_id) else: await self.send_json({ 'error': 'unknown command' }) async def disconnect(self, code): await database_sync_to_async(self.change_user_status)(False) async def send_notification(self, action): await self.send_json(action) async def subscribe(self, article_id): await self.channel_layer.group_add( 'article_{0}'.format(article_id), self.channel_name ) async def unsubscribe(self, article_id): await self.channel_layer.group_discard( 'article_{0}'.format(article_id), self.channel_name ) def get_users_subscription(self): return CommentSubscribe.objects.filter( user=self.scope['user'] ) def change_user_status(self, online): return UserStatus.objects.filter( user=self.scope['user'] ).update(online=online)views.py
from .notify import send_comment_notificationclass CreateComment(CreateView): ... def form_valid(self, form): ... super().form_valid(form) send_comment_notification('create', article_id)class UpdateComment(UpdateView): ... def form_valid(self, form): ... super().form_valid(form) send_comment_notification('update', article_id)class DeleteComment(DeleteView): ... def delete(self, request, *args, **kwargs): ... send_comment_notification('delete', article_id)notify.py
...def send_comment_notification(action, article_id): channel_layer = get_channel_layer() group_name = 'article_{0}'.format(article_id) async_to_sync(channel_layer.group_send)( group_name, { 'type': 'send.notification', 'data': { 'action': action } } )You mustlog in to answer this question.
Explore related questions
See similar questions with these tags.
