Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Shavkatjon-O committed Aug 29, 2024
1 parent 26364e4 commit efd7df5
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 107 deletions.
6 changes: 1 addition & 5 deletions apps/chats/admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
from django.contrib import admin
from apps.chats.models import Message

# Register your models here.

from apps.chats.models import Chat, Message

admin.site.register(Chat)
admin.site.register(Message)
54 changes: 6 additions & 48 deletions apps/chats/consumers.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,32 @@
import json
# consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.contrib.auth.models import User
from .models import Message, Chat
import json


class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
# Extract chat_id from URL route
self.chat_id = self.scope["url_route"]["kwargs"]["chat_id"]
self.room_group_name = f"chat_{self.chat_id}"

# Ensure channel_layer is available
if self.channel_layer is None:
await self.close()
return

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

# Notify users about the new connection
await self.channel_layer.group_send(
self.room_group_name, {"type": "user_status", "status": "Online"}
)
await self.accept()

async def disconnect(self, close_code):
# Leave room group
if self.channel_layer is None:
return

await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

# Notify users about the disconnection
await self.channel_layer.group_send(
self.room_group_name, {"type": "user_status", "status": "Offline"}
)

async def receive(self, text_data):
# Process incoming message
text_data_json = json.loads(text_data)
message = text_data_json.get("message", "")
user_id = text_data_json.get("user_id")

# Retrieve chat and user
chat = await database_sync_to_async(Chat.objects.get)(id=self.chat_id)
user = await database_sync_to_async(User.objects.get)(id=user_id)
message = text_data_json["message"]
user = self.scope["user"].username

# Save the message to the database
await database_sync_to_async(Message.objects.create)(
chat=chat, user=user, content=message
)

# Broadcast the message to the chat group
await self.channel_layer.group_send(
self.room_group_name,
{"type": "chat_message", "message": message, "user": user.username},
{"type": "chat_message", "message": message, "user": user},
)

async def chat_message(self, event):
# Handle incoming message
message = event["message"]
user = event["user"]

# Send message to WebSocket
await self.send(text_data=json.dumps({"message": message, "user": user}))

async def user_status(self, event):
# Handle user status update
status = event["status"]

# Send status update to WebSocket
await self.send(text_data=json.dumps({"status": status}))
2 changes: 1 addition & 1 deletion apps/chats/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def __str__(self):


class Message(BaseModel):
chat = models.ForeignKey(Chat, on_delete=models.CASCADE, related_name="messages")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="messages")
chat = models.ForeignKey(Chat, on_delete=models.CASCADE, related_name="messages")
text = models.TextField()

def __str__(self):
Expand Down
5 changes: 3 additions & 2 deletions apps/chats/routing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.urls import path
# routing.py
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
path("ws/chat/<int:chat_id>/", consumers.ChatConsumer.as_asgi()),
re_path(r"ws/chats/(?P<chat_id>\d+)/$", consumers.ChatConsumer.as_asgi()),
]
33 changes: 31 additions & 2 deletions apps/chats/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers
from django.contrib.auth import get_user_model
from apps.chats.models import Chat, Message
from apps.chats.models import Message, Chat

User = get_user_model()

Expand All @@ -18,7 +18,7 @@ class Meta:


class MessageSerializer(serializers.ModelSerializer):
user = UserSerializer()
user = serializers.StringRelatedField()

class Meta:
model = Message
Expand All @@ -44,3 +44,32 @@ class Meta:
"messages",
"created_at",
)


# class MessageSerializer(serializers.ModelSerializer):
# user = UserSerializer()

# class Meta:
# model = Message
# fields = (
# "id",
# "chat",
# "user",
# "text",
# "created_at",
# )


# class ChatSerializer(serializers.ModelSerializer):
# users = UserSerializer(many=True)
# messages = MessageSerializer(many=True, read_only=True)

# class Meta:
# model = Chat
# fields = (
# "id",
# "title",
# "users",
# "messages",
# "created_at",
# )
49 changes: 38 additions & 11 deletions apps/chats/urls.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
# from django.urls import path
# from . import views

# urlpatterns = [
# path("chats/", views.ChatListView.as_view(), name="chat-list"),
# path("chats/<int:pk>/", views.ChatDetailView.as_view(), name="chat-detail"),
# path(
# "chats/<int:pk>/messages/", views.MessageListView.as_view(), name="message-list"
# ),
# path(
# "chats/<int:pk>/messages/<int:message_pk>/",
# views.MessageDetailView.as_view(),
# name="message-detail",
# ),
# path("users/", views.UserListView.as_view(), name="user-list"),
# path("users/<int:pk>/", views.UserDetailView.as_view(), name="user-detail"),
# ]


# urlpatterns = [
# path("users/", views.UserListView.as_view(), name="user-list"),
# ]

# urls.py
from django.urls import path
from . import views
from .views import (
ChatListCreateView,
ChatDetailView,
MessageListCreateView,
MessageDetailView,
UserListView,
)

urlpatterns = [
path("chats/", views.ChatListView.as_view(), name="chat-list"),
path("chats/<int:pk>/", views.ChatDetailView.as_view(), name="chat-detail"),
path(
"chats/<int:pk>/messages/", views.MessageListView.as_view(), name="message-list"
),
path("", ChatListCreateView.as_view(), name="chat-list-create"),
path("<int:pk>/", ChatDetailView.as_view(), name="chat-detail"),
path(
"chats/<int:pk>/messages/<int:message_pk>/",
views.MessageDetailView.as_view(),
name="message-detail",
"<int:chat_id>/messages/",
MessageListCreateView.as_view(),
name="message-list-create",
),
path("users/", views.UserListView.as_view(), name="user-list"),
path("users/<int:pk>/", views.UserDetailView.as_view(), name="user-detail"),
path("messages/<int:pk>/", MessageDetailView.as_view(), name="message-detail"),
path("users/", UserListView.as_view(), name="user-list"),
]
39 changes: 20 additions & 19 deletions apps/chats/views.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
from rest_framework import generics
from apps.chats import serializers, models

from apps.chats.models import Chat, Message, User
from apps.chats.serializers import ChatSerializer, MessageSerializer, UserSerializer

class UserListView(generics.ListAPIView):
queryset = models.User.objects.all()
serializer_class = serializers.UserSerializer

class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer

class UserDetailView(generics.RetrieveAPIView):
queryset = models.User.objects.all()
serializer_class = serializers.UserSerializer

class ChatListCreateView(generics.ListCreateAPIView):
queryset = Chat.objects.all()
serializer_class = ChatSerializer

class ChatListView(generics.ListCreateAPIView):
queryset = models.Chat.objects.all()
serializer_class = serializers.ChatSerializer

class ChatDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Chat.objects.all()
serializer_class = ChatSerializer

class ChatDetailView(generics.RetrieveAPIView):
queryset = models.Chat.objects.all()
serializer_class = serializers.ChatSerializer

class MessageListCreateView(generics.ListCreateAPIView):
queryset = Message.objects.all()
serializer_class = MessageSerializer

class MessageListView(generics.ListAPIView):
queryset = models.Message.objects.all()
serializer_class = serializers.MessageSerializer
def get_queryset(self):
chat_id = self.kwargs.get("chat_id")
return Message.objects.filter(chat_id=chat_id)


class MessageDetailView(generics.RetrieveAPIView):
queryset = models.Message.objects.all()
serializer_class = serializers.MessageSerializer
class MessageDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Message.objects.all()
serializer_class = MessageSerializer
63 changes: 44 additions & 19 deletions core/asgi.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,67 @@
# """
# ASGI config for core project.
# # """
# # ASGI config for core project.

# It exposes the ASGI callable as a module-level variable named ``application``.
# # It exposes the ASGI callable as a module-level variable named ``application``.

# # For more information on this file, see
# # https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
# # """

# # import os

# # from django.core.asgi import get_asgi_application

# # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

# # application = get_asgi_application()

# For more information on this file, see
# https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
# """

# import os
# import django

# django.setup()
# from django.core.asgi import get_asgi_application
# from channels.routing import ProtocolTypeRouter, URLRouter
# from channels.auth import AuthMiddlewareStack
# from apps.chats.consumers import ChatConsumer
# from django.urls import re_path

# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings")

# application = get_asgi_application()
# application = ProtocolTypeRouter(
# {
# "http": get_asgi_application(),
# "websocket": AuthMiddlewareStack(
# URLRouter(
# [
# re_path(r"ws/chat/(?P<chat_id>\d+)/$", ChatConsumer.as_asgi()),
# ]
# )
# ),
# }
# )


import os
# asgi.py
import django

django.setup()
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from apps.chats.consumers import ChatConsumer
from django.urls import re_path
from apps.chats import routing

import environ

env = environ.Env()
env.read_env(".env")

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings")
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')

application = ProtocolTypeRouter(
{
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
[
re_path(r"ws/chat/(?P<chat_id>\d+)/$", ChatConsumer.as_asgi()),
]
)
),
"websocket": AuthMiddlewareStack(URLRouter(routing.websocket_urlpatterns)),
}
)

0 comments on commit efd7df5

Please sign in to comment.