This commit is contained in:
2026-06-11 21:22:02 -06:00
parent a335eb22e8
commit 4f288a1fef
4 changed files with 113 additions and 90 deletions

View File

@@ -8,6 +8,7 @@ from django.contrib.auth.decorators import login_required
from django.db.models import Count, Prefetch
from .models import Conversation, Message
from .utils import get_preceding_user_message
from .schemas import ConversationOut, MessageOut, PromptHistoryItemOut
from account.models import RoleChoices
@@ -166,16 +167,15 @@ def delete_message_pair(request, message_id: int):
if asst_msg.conversation.user != request.user and request.user.role != RoleChoices.SUPER:
raise HttpError(403, "只能删除自己的消息")
if asst_msg.submission_id and request.user.role != RoleChoices.SUPER:
from submission.models import Rating, SubmissionAward
has_ratings = Rating.objects.filter(submission_id=asst_msg.submission_id).exists()
has_awards = SubmissionAward.objects.filter(submission_id=asst_msg.submission_id).exists()
if has_ratings or has_awards:
raise HttpError(400, "该消息关联的提交已被评分或获奖,无法删除")
# Find the preceding user message
user_msg = (
Message.objects.filter(
conversation=asst_msg.conversation,
created__lt=asst_msg.created,
role="user",
)
.order_by("-created")
.first()
)
user_msg = get_preceding_user_message(asst_msg)
# Delete messages first, then submission
submission_id = asst_msg.submission_id # capture before deletion nulls it
@@ -187,10 +187,7 @@ def delete_message_pair(request, message_id: int):
submission_deleted = False
if submission_id:
from submission.models import Submission as SubmissionModel
try:
SubmissionModel.objects.filter(id=submission_id).delete()
submission_deleted = True
except Exception:
pass
SubmissionModel.objects.filter(id=submission_id).delete()
submission_deleted = True
return {"deleted": True, "submission_deleted": submission_deleted}

View File

@@ -1,8 +1,8 @@
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.db.models import Count
from .models import Conversation, Message
from .models import Message
from .utils import get_or_create_active_conversation
from .llm import stream_chat, extract_code, stream_guidance, parse_guidance_response
@@ -79,15 +79,7 @@ class PromptConsumer(AsyncWebsocketConsumer):
@database_sync_to_async
def get_or_create_conversation(self):
conv = (
Conversation.objects.filter(user=self.user, task_id=self.task_id)
.annotate(msg_count=Count("messages"))
.order_by("-msg_count", "-created")
.first()
)
if not conv:
conv = Conversation.objects.create(user=self.user, task_id=self.task_id)
return conv
return get_or_create_active_conversation(self.user, self.task_id)
@database_sync_to_async
def delete_message(self, message):
@@ -195,15 +187,7 @@ class GuidanceConsumer(AsyncWebsocketConsumer):
@database_sync_to_async
def get_or_create_conversation(self):
conv = (
Conversation.objects.filter(user=self.user, task_id=self.task_id)
.annotate(msg_count=Count("messages"))
.order_by("-msg_count", "-created")
.first()
)
if not conv:
conv = Conversation.objects.create(user=self.user, task_id=self.task_id)
return conv
return get_or_create_active_conversation(self.user, self.task_id)
@database_sync_to_async
def delete_message(self, message):

32
prompt/utils.py Normal file
View File

@@ -0,0 +1,32 @@
from django.db.models import Count, Q
from .models import Conversation
def get_active_conversation(user, task_id):
"""Return the conversation with the most messages for this user+task, or None."""
return (
Conversation.objects.filter(user=user, task_id=task_id)
.annotate(msg_count=Count("messages"))
.order_by("-msg_count", "-created")
.first()
)
def get_or_create_active_conversation(user, task_id):
conv = get_active_conversation(user, task_id)
if not conv:
conv = Conversation.objects.create(user=user, task_id=task_id)
return conv
def get_preceding_user_message(asst_msg):
"""Return the user message immediately preceding an assistant message in its conversation."""
return (
asst_msg.conversation.messages.filter(role="user")
.filter(
Q(created__lt=asst_msg.created)
| Q(created=asst_msg.created, id__lt=asst_msg.id)
)
.order_by("-created", "-id")
.first()
)