如何添加收件箱通知系统并从一个用户 django 频道中删除消息
How to add inbox notification system and delete message from one user django channels
我正在尝试使用 Django、Django-rest-framework 和 Django-channels 构建一个类似 Messenger 的应用程序。
现在我只能将消息从一个用户发送到另一个用户。但我想添加这样的功能,新消息将与用户名一起位于收件箱的顶部,并且一个用户可以从他身边删除消息,就像信使,什么应用程序等。当有人发送消息时,他的消息将打开顶部并将显示通知。
我找不到完美的模型设计和完美的系统。
Model.py
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='sender_messages')
receiver = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='receiver_messages')
text = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} to {}'.format(self.sender.name, self.receiver.name)
消费者
import json
from asgiref.sync import async_to_sync
from django.contrib.auth import get_user_model
from channels.generic.websocket import WebsocketConsumer
from .models import Message
User = get_user_model()
class ChatConsumer(WebsocketConsumer):
def connect(self):
"""
Join channel group by chatname.
"""
self.group_name = 'chat_{0}'.format(self.scope['url_route']['kwargs']['chatname'])
async_to_sync(self.channel_layer.group_add)(
self.group_name,
self.channel_name,
)
self.accept()
def disconnect(self, close_code):
"""
Leave channel by group name.
"""
async_to_sync(self.channel_layer.group_discard)(
self.group_name,
self.channel_name
)
def receive(self, text_data):
"""
Receive message from websocket and send message to channel group.
"""
text_data_json = json.loads(text_data)
name = text_data_json['name']
message = text_data_json['message']
# Store message.
receiver = User.objects.get(
name=self.group_name.replace('chat_', '')
.replace(self.scope['user'].name, '')
.replace('-', ''))
Message(sender=self.scope['user'], receiver=receiver, text=message).save()
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
'type': 'chat_message',
'name': name,
'message': message,
}
)
def chat_message(self, event):
"""
Receive message from channel group and send message to websocket.
"""
self.send(text_data=json.dumps({
'name': event['name'],
'message': event['message'],
}))
查看
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# List all users for chatting. Except myself.
context['users'] = User.objects.exclude(id=self.request.user.id) \
.values('name')
context['users'] = User.objects.exclude(gender=self.request.user.gender)
return context
class ChatHomeApi(viewsets.ModelViewSet):
serializer_class = InboxRetrieveSerializer
authentication_classes = [TokenAuthentication]
pagination_class = GeneralPagination
def get_queryset(self):
return Chat_Inbox.objects.filter(sender=self.request.user)
class ChatView(LoginRequiredMixin, TemplateView):
template_name = 'chat.html'
def dispatch(self, request, **kwargs):
# Get the person we are chatting with, if not exist raise 404.
receiver_name = kwargs['chatname'].replace(
request.user.name, '').replace('-', '')
kwargs['receiver'] = get_object_or_404(User, name=receiver_name)
return super().dispatch(request, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['receiver'] = kwargs['receiver']
return context
class MessagesAPIView(LoginRequiredMixin, View):
def get(self, request, chatname):
# Grab two users based on the chat name.
users = User.objects.filter(name__in=chatname.split('-'))
# Filters messages between this two users.
result = Message.objects.filter(
Q(sender=users[0], receiver=users[1]) | Q(sender=users[1], receiver=users[0])
).annotate(
name=F('sender__name'), message=F('text'),
).order_by('date_created').values('name', 'message', 'date_created')
return JsonResponse(list(result), safe=False)
所以基本上,我想在收件箱顶部显示新消息,用户可以从他这边删除消息,这可能不会影响其他用户。
提前致谢
对于订购,您可以将时间戳与所有消息一起发送并存储该时间戳。
现在在检索消息时,您可以在 Django 中使用 order_by
检索它们。
例如,
def receive(self, text_data):
text_data_json = json.loads(text_data)
name = text_data_json['name']
message = text_data_json['message']
timestamp = timezone.now()
# Store message.
receiver = User.objects.get(
name=self.group_name.replace('chat_', '')
.replace(self.scope['user'].name, '')
.replace('-', ''))
Message(sender=self.scope['user'], receiver=receiver, text=message).save()
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
'type': 'chat_message',
'name': name,
'message': message,
'timestamp': timestamp.isoformat()
}
)
async def chat_message(self, event):
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': 'Message Received Successfully',
'data': {
'message': event['message'],
'message_type': event['message_type'],
'timestamp': event['timestamp']
}
}))
我正在尝试使用 Django、Django-rest-framework 和 Django-channels 构建一个类似 Messenger 的应用程序。 现在我只能将消息从一个用户发送到另一个用户。但我想添加这样的功能,新消息将与用户名一起位于收件箱的顶部,并且一个用户可以从他身边删除消息,就像信使,什么应用程序等。当有人发送消息时,他的消息将打开顶部并将显示通知。 我找不到完美的模型设计和完美的系统。
Model.py
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='sender_messages')
receiver = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='receiver_messages')
text = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} to {}'.format(self.sender.name, self.receiver.name)
消费者
import json
from asgiref.sync import async_to_sync
from django.contrib.auth import get_user_model
from channels.generic.websocket import WebsocketConsumer
from .models import Message
User = get_user_model()
class ChatConsumer(WebsocketConsumer):
def connect(self):
"""
Join channel group by chatname.
"""
self.group_name = 'chat_{0}'.format(self.scope['url_route']['kwargs']['chatname'])
async_to_sync(self.channel_layer.group_add)(
self.group_name,
self.channel_name,
)
self.accept()
def disconnect(self, close_code):
"""
Leave channel by group name.
"""
async_to_sync(self.channel_layer.group_discard)(
self.group_name,
self.channel_name
)
def receive(self, text_data):
"""
Receive message from websocket and send message to channel group.
"""
text_data_json = json.loads(text_data)
name = text_data_json['name']
message = text_data_json['message']
# Store message.
receiver = User.objects.get(
name=self.group_name.replace('chat_', '')
.replace(self.scope['user'].name, '')
.replace('-', ''))
Message(sender=self.scope['user'], receiver=receiver, text=message).save()
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
'type': 'chat_message',
'name': name,
'message': message,
}
)
def chat_message(self, event):
"""
Receive message from channel group and send message to websocket.
"""
self.send(text_data=json.dumps({
'name': event['name'],
'message': event['message'],
}))
查看
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# List all users for chatting. Except myself.
context['users'] = User.objects.exclude(id=self.request.user.id) \
.values('name')
context['users'] = User.objects.exclude(gender=self.request.user.gender)
return context
class ChatHomeApi(viewsets.ModelViewSet):
serializer_class = InboxRetrieveSerializer
authentication_classes = [TokenAuthentication]
pagination_class = GeneralPagination
def get_queryset(self):
return Chat_Inbox.objects.filter(sender=self.request.user)
class ChatView(LoginRequiredMixin, TemplateView):
template_name = 'chat.html'
def dispatch(self, request, **kwargs):
# Get the person we are chatting with, if not exist raise 404.
receiver_name = kwargs['chatname'].replace(
request.user.name, '').replace('-', '')
kwargs['receiver'] = get_object_or_404(User, name=receiver_name)
return super().dispatch(request, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['receiver'] = kwargs['receiver']
return context
class MessagesAPIView(LoginRequiredMixin, View):
def get(self, request, chatname):
# Grab two users based on the chat name.
users = User.objects.filter(name__in=chatname.split('-'))
# Filters messages between this two users.
result = Message.objects.filter(
Q(sender=users[0], receiver=users[1]) | Q(sender=users[1], receiver=users[0])
).annotate(
name=F('sender__name'), message=F('text'),
).order_by('date_created').values('name', 'message', 'date_created')
return JsonResponse(list(result), safe=False)
所以基本上,我想在收件箱顶部显示新消息,用户可以从他这边删除消息,这可能不会影响其他用户。 提前致谢
对于订购,您可以将时间戳与所有消息一起发送并存储该时间戳。
现在在检索消息时,您可以在 Django 中使用 order_by
检索它们。
例如,
def receive(self, text_data):
text_data_json = json.loads(text_data)
name = text_data_json['name']
message = text_data_json['message']
timestamp = timezone.now()
# Store message.
receiver = User.objects.get(
name=self.group_name.replace('chat_', '')
.replace(self.scope['user'].name, '')
.replace('-', ''))
Message(sender=self.scope['user'], receiver=receiver, text=message).save()
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
'type': 'chat_message',
'name': name,
'message': message,
'timestamp': timestamp.isoformat()
}
)
async def chat_message(self, event):
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': 'Message Received Successfully',
'data': {
'message': event['message'],
'message_type': event['message_type'],
'timestamp': event['timestamp']
}
}))