importloggingfromtypingimportList,Optional,Unionfromasgiref.syncimportsync_to_asyncfromdjango.confimportsettingsfromdjango.contrib.auth.modelsimportAbstractUser,AnonymousUserfromdjango.dbimportmodelsfromlangchain_core.messagesimportAIMessage,HumanMessage,SystemMessagefromlangchain_core.runnablesimportAddableDictfrom.jsonimportXJSONDecoder,XJSONEncoderlogger=logging.getLogger(__name__)UserType=Union[AbstractUser,AnonymousUser]ConversationMessageType=Union[SystemMessage,HumanMessage,AIMessage,AddableDict]classConversationMessageManager(models.Manager):asyncdefaget_histories(self,conversation:Optional["Conversation"]=None,user:Optional[UserType]=None,)->List[ConversationMessageType]:ifconversationisNone:return[]@sync_to_asyncdefget_messages()->List[ConversationMessageType]:qs=self.get_queryset().filter(conversation=conversation,user=user,)return[conversation_message.contentforconversation_messageinqs]returnawaitget_messages()asyncdefaadd_messages(self,conversation:"Conversation",user:Optional[UserType],messages:List[ConversationMessageType],)->None:awaitself.get_queryset().abulk_create([ConversationMessage(conversation=conversation,user=user,content=message,)formessageinmessages])classConversation(models.Model):"""대화방 모델. Attributes: user (:class:`django.db.models.ForeignKey`): 대화방을 소유한 사용자. settings.AUTH_USER_MODEL을 참조하는 외래키입니다. `null=True`이므로 사용자 할당없이도 생성할 수 있습니다. """user=models.ForeignKey(to=settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True)defclear(self):"""소속된 모든 ConversationMessage를 데이터베이스에서 제거합니다."""self.conversationmessage_set.all().delete()
[문서]classConversationMessage(models.Model):"""대화 메시지를 저장하는 모델. Attributes: MESSAGE_CLASS_MAP (dict): 메시지 타입별 클래스 매핑 딕셔너리 (system, human, ai) conversation (:class:`django.db.models.ForeignKey`): 메시지가 속한 대화방 ForeignKey user (:class:`django.db.models.ForeignKey`): 메시지를 작성한 사용자 ForeignKey (null 가능) content (:class:`django.db.models.JSONField`): 메시지 내용을 저장하는 JSONField * :class:`pyhub_ai.encoders.XJSONEncoder` 를 통해 JSON 인코딩 * :class:`pyhub_ai.encoders.XJSONDecoder` 를 통해 JSON 디코딩 objects (:class:`ConversationMessageManager`): ConversationMessageManager 커스텀 매니저 """MESSAGE_CLASS_MAP={"system":SystemMessage,"human":HumanMessage,"ai":AIMessage,}conversation=models.ForeignKey(to=Conversation,on_delete=models.CASCADE,)user=models.ForeignKey(to=settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,)content=models.JSONField(default=dict,encoder=XJSONEncoder,decoder=XJSONDecoder,)objects=ConversationMessageManager()