11
\$\begingroup\$

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 AsyncJsonWebsocketConsumer
from channels.db import database_sync_to_async
from project.apps.account.models import UserStatus
from .models import CommentSubscribe
class 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_notification
class 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
 }
 }
 )
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Dec 18, 2018 at 13:43
\$\endgroup\$

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.