From 58f0b129730e77a4ab27f745eb2aa8cf65bcf9b5 Mon Sep 17 00:00:00 2001 From: alireza Date: Mon, 25 Nov 2024 13:46:29 +0330 Subject: [PATCH] feat(chat models): update room message models --- apps/account/models/user.py | 2 +- apps/chat/admin.py | 51 +++++++++++++- .../migrations/0002_auto_20241125_1219.py | 49 +++++++++++++ apps/chat/models.py | 68 +++++++++++++++---- apps/course/apps.py | 3 + apps/course/signals.py | 19 ++++++ config/urls.py | 1 + 7 files changed, 176 insertions(+), 17 deletions(-) create mode 100644 apps/chat/migrations/0002_auto_20241125_1219.py create mode 100644 apps/course/signals.py diff --git a/apps/account/models/user.py b/apps/account/models/user.py index acee270..cbed67d 100644 --- a/apps/account/models/user.py +++ b/apps/account/models/user.py @@ -72,7 +72,7 @@ class User(AbstractUser): # self.email = None def __str__(self): - return f"{self.email} - {self.get_full_name()}" + return f"{self.email} - {self.get_full_name()} - ({self.user_type})" def get_full_name(self): diff --git a/apps/chat/admin.py b/apps/chat/admin.py index 8c38f3f..5d69589 100644 --- a/apps/chat/admin.py +++ b/apps/chat/admin.py @@ -1,3 +1,52 @@ from django.contrib import admin -# Register your models here. +from apps.chat.models import RoomMessage, ChatMessage + + + + +@admin.register(RoomMessage) +class RoomMessageAdmin(admin.ModelAdmin): + list_display = ( + 'name', 'room_type', 'course', 'initiator', 'recipient', 'created_at', + ) + list_filter = ('room_type', 'created_at', 'updated_at', 'course') + search_fields = ('name', 'description', 'course__title', 'initiator__username', 'recipient__username') + ordering = ('-created_at',) + readonly_fields = ('created_at', 'updated_at') + fieldsets = ( + (None, { + 'fields': ('name', 'description', 'room_type') + }), + ('Relations', { + 'fields': ('course', 'initiator', 'recipient') + }), + ('Timestamps', { + 'fields': ('created_at', 'updated_at') + }), + ) + + +@admin.register(ChatMessage) +class ChatMessageAdmin(admin.ModelAdmin): + list_display = ( + 'room', 'sender', 'content_type', 'content_size', 'sent_at', 'is_deleted' + ) + list_filter = ('content_type', 'is_deleted', 'sent_at', 'updated_at') + search_fields = ('room__name', 'sender__username', 'content') + ordering = ('-sent_at',) + readonly_fields = ('sent_at', 'updated_at') + fieldsets = ( + (None, { + 'fields': ('room', 'sender', 'content', 'content_type') + }), + ('Additional Info', { + 'fields': ('content_size',) + }), + ('Status', { + 'fields': ('is_deleted', 'deleted_at') + }), + ('Timestamps', { + 'fields': ('sent_at', 'updated_at') + }), + ) diff --git a/apps/chat/migrations/0002_auto_20241125_1219.py b/apps/chat/migrations/0002_auto_20241125_1219.py new file mode 100644 index 0000000..9b27b10 --- /dev/null +++ b/apps/chat/migrations/0002_auto_20241125_1219.py @@ -0,0 +1,49 @@ +# Generated by Django 3.2.4 on 2024-11-25 12:19 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0004_auto_20241122_1913'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('chat', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='chatmessage', + name='course', + ), + migrations.RemoveField( + model_name='chatmessage', + name='is_to_professor', + ), + migrations.RemoveField( + model_name='chatmessage', + name='recipient', + ), + migrations.CreateModel( + name='RoomMessage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Room Name')), + ('description', models.TextField(blank=True, null=True, verbose_name='Description')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), + ('room_type', models.CharField(choices=[('group', 'Group'), ('private', 'Private')], default='group', max_length=10, verbose_name='Room Type')), + ('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='room_messages', to='course.course', verbose_name='Course')), + ('initiator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='initiated_rooms', to=settings.AUTH_USER_MODEL, verbose_name='Initiator')), + ('recipient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='messages_received', to=settings.AUTH_USER_MODEL, verbose_name='Recipient')), + ], + ), + migrations.AddField( + model_name='chatmessage', + name='room', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='chat.roommessage', verbose_name='Room'), + preserve_default=False, + ), + ] diff --git a/apps/chat/models.py b/apps/chat/models.py index 7baad17..07e7b92 100644 --- a/apps/chat/models.py +++ b/apps/chat/models.py @@ -5,6 +5,55 @@ from apps.account.models import User, ProfessorUser from apps.course.models import Course + +class RoomMessage(models.Model): + class RoomTypeChoices(models.TextChoices): + GROUP = 'group', 'Group' + PRIVATE = 'private', 'Private' + + name = models.CharField( + max_length=255, + verbose_name="Room Name" + ) + description = models.TextField( + verbose_name="Description", + blank=True, + null=True + ) + course = models.ForeignKey(Course,on_delete=models.CASCADE, null=True, blank=True ,related_name="room_messages", verbose_name="Course") + initiator = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name="initiated_rooms", + verbose_name="Initiator" + ) + recipient = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name="messages_received", + verbose_name="Recipient", + null=True, + blank=True + ) + created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created At") + updated_at = models.DateTimeField( + auto_now=True, + verbose_name="Updated At" + ) + room_type = models.CharField( + max_length=10, + choices=RoomTypeChoices.choices, + default=RoomTypeChoices.GROUP, + verbose_name="Room Type" + ) + + def __str__(self): + if self.room_type == self.RoomTypeChoices.GROUP: + return f"Group Room: {self.course.title if self.course else 'N/A'}" + return f"Private Room with {self.recipient}" + + + class ChatMessage(models.Model): class ChatTypeChoices(models.TextChoices): TEXT = 'text', 'Text' @@ -12,11 +61,11 @@ class ChatMessage(models.Model): AUDIO = 'audio', 'Audio' IMAGE = 'image', 'Image' - course = models.ForeignKey( - Course, + room = models.ForeignKey( + RoomMessage, on_delete=models.CASCADE, related_name="messages", - verbose_name="Course" + verbose_name="Room", ) sender = models.ForeignKey( User, @@ -24,15 +73,6 @@ class ChatMessage(models.Model): related_name="messages_sent", verbose_name="Sender" ) - recipient = models.ForeignKey( - User, - on_delete=models.CASCADE, - related_name="messages_received", - verbose_name="Recipient", - null=True, - blank=True - - ) content = models.TextField(verbose_name="Message Content") content_type = models.CharField( max_length=10, @@ -45,7 +85,6 @@ class ChatMessage(models.Model): blank=True, null=True ) - is_to_professor = models.BooleanField(default=False, verbose_name="Is to Professor") sent_at = models.DateTimeField(auto_now_add=True, verbose_name="Sent At") updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated At") @@ -53,8 +92,7 @@ class ChatMessage(models.Model): is_deleted = models.BooleanField(default=False, verbose_name="Is deleted") def __str__(self): - return f"Message from {self.sender} to {self.recipient or 'Group'} in {self.course.title}" - + return f"Message from {self.sender} in {self.room}" \ No newline at end of file diff --git a/apps/course/apps.py b/apps/course/apps.py index ddc8553..b56f637 100644 --- a/apps/course/apps.py +++ b/apps/course/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class CourseConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'apps.course' + + def ready(self): + import apps.course.signals \ No newline at end of file diff --git a/apps/course/signals.py b/apps/course/signals.py new file mode 100644 index 0000000..d0edf96 --- /dev/null +++ b/apps/course/signals.py @@ -0,0 +1,19 @@ + +from django.db.models.signals import post_save +from django.dispatch import receiver +from apps.course.models import Course +from apps.chat.models import RoomMessage + + +@receiver(post_save, sender=Course) +def create_room_message_for_course(sender, instance, created, **kwargs): + if created: # فقط برای موارد جدید اجرا شود + RoomMessage.objects.create( + name=f"{instance.title} - Group", + description=f"Group chat for course: {instance.title}", + initiator=instance.professor, # استاد به‌عنوان سازنده اتاق + course=instance, + room_type=RoomMessage.RoomTypeChoices.GROUP + ) + + \ No newline at end of file diff --git a/config/urls.py b/config/urls.py index 3b9716e..0eaccb1 100644 --- a/config/urls.py +++ b/config/urls.py @@ -36,6 +36,7 @@ api_patterns = [ path('account/', include('apps.account.urls')), path('courses/', include('apps.course.urls')), + path('upload-tmp-media/', UploadTmpMedia.as_view()), ]