From 9849c4084e537b52c8238d9d6db40bd42d7d5e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=9D=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Thu, 15 Jan 2026 12:15:55 +0300 Subject: [PATCH] =?UTF-8?q?refactor(communications):=20=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Обновлен consumers.py: - serialize_message: использование forward_metadata вместо forwarded_from_* - _get_message: prefetch forward_metadata и MessageEditHistory - _edit_message: создание MessageEditHistory записей вместо JSON Обновлен serializers.py: - MessageCreateSerializer: удалены forwarded_from_* из fields - Чистка Meta.fields от удаленных полей модели Обратная совместимость: - WebSocket payload не изменился (forwarded_from структура сохранена) - API endpoints работают без изменений Ref: COMMUNICATIONS_API_REFACTORING.md --- backend/api/v1/communications/serializers.py | 4 +- backend/communications/consumers.py | 72 +++++++++++--------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/backend/api/v1/communications/serializers.py b/backend/api/v1/communications/serializers.py index 2a727595..ac893ab6 100644 --- a/backend/api/v1/communications/serializers.py +++ b/backend/api/v1/communications/serializers.py @@ -238,9 +238,7 @@ class MessageCreateSerializer(serializers.ModelSerializer): class Meta: model = Message fields = [ - 'content', 'chat', 'reply_to', 'is_forwarded', - 'forwarded_from_author', 'forwarded_from_message_id', - 'forwarded_from_chat_name', 'forwarded_from_created_at' + 'content', 'chat', 'reply_to', 'is_forwarded' ] def validate(self, attrs): diff --git a/backend/communications/consumers.py b/backend/communications/consumers.py index e329fc3d..6899a098 100644 --- a/backend/communications/consumers.py +++ b/backend/communications/consumers.py @@ -42,31 +42,37 @@ def serialize_message(m: Message) -> dict: "has_attachments": m.has_attachments, } - # Информация о пересылке - if m.is_forwarded and m.forwarded_from_author: - forwarded_data = { - "author_id": m.forwarded_from_author.id, - "author_name": ( - m.forwarded_from_author.get_full_name() - or m.forwarded_from_author.username - ), - "message_id": m.forwarded_from_message_id, - } - - # Добавляем дату оригинального сообщения - if m.forwarded_from_created_at: - forwarded_data["created_at"] = ( - m.forwarded_from_created_at.strftime("%d.%m.%Y %H:%M") - ) - forwarded_data["created_ts"] = int( - m.forwarded_from_created_at.timestamp() * 1000 - ) - - # Добавляем название исходного чата - if m.forwarded_from_chat_name: - forwarded_data["chat_name"] = m.forwarded_from_chat_name - - data["forwarded_from"] = forwarded_data + # Информация о пересылке (используем forward_metadata) + if m.is_forwarded: + try: + metadata = m.forward_metadata + forwarded_data = { + "author_id": metadata.original_author.id if metadata.original_author else None, + "author_name": ( + metadata.original_author.get_full_name() if metadata.original_author + else metadata.original_author.username if metadata.original_author + else "Неизвестно" + ), + "message_id": metadata.original_message_id if metadata.original_message else None, + } + + # Добавляем дату оригинального сообщения + if metadata.original_created_at: + forwarded_data["created_at"] = ( + metadata.original_created_at.strftime("%d.%m.%Y %H:%M") + ) + forwarded_data["created_ts"] = int( + metadata.original_created_at.timestamp() * 1000 + ) + + # Добавляем название исходного чата + if metadata.original_chat_name: + forwarded_data["chat_name"] = metadata.original_chat_name + + data["forwarded_from"] = forwarded_data + except Exception: + # Если метаданных нет, просто не добавляем информацию о пересылке + pass # Реакции - сериализуем из связанной модели MessageReaction reactions_summary = {} @@ -591,7 +597,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): def _get_message(self, message_id: int) -> Message: return Message.objects.select_related( 'author', 'reply_to', 'reply_to__author', - 'forwarded_from_author', 'poll' + 'forward_metadata', 'forward_metadata__original_author', 'poll' ).prefetch_related( 'attachments', 'reactions', 'reactions__user', 'poll__options' ).get(pk=message_id) @@ -602,15 +608,17 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): @database_sync_to_async def _edit_message(self, message_id: int, user, new_content: str) -> bool: + from .models import MessageEditHistory + try: msg = Message.objects.get(pk=message_id, author=user) - if not msg.is_edited: - msg.edit_history = [] - msg.edit_history.append({ - 'timestamp': timezone.now().isoformat(), - 'old_content': msg.content - }) + # Сохраняем старый контент в историю редактирования + MessageEditHistory.objects.create( + message=msg, + previous_content=msg.content, + edited_by=user + ) msg.content = new_content msg.is_edited = True