Files

107 lines
3.4 KiB
Python

from adrf.serializers import (
ModelSerializer, CharField, SerializerMethodField,
)
from django.contrib.auth import get_user_model
from django.core.exceptions import SynchronousOnlyOperation
from .models import Message, SystemMessage, SystemMessageRead
User = get_user_model()
async def _load_sender(obj):
"""优先命中 select_related 预加载缓存;未预加载时异步回源,避免外键懒加载"""
try:
return obj.sender
except SynchronousOnlyOperation:
if not obj.sender_id:
return None
return await User.objects.aget(pk=obj.sender_id)
class MessageListSerializer(ModelSerializer):
sender_name = SerializerMethodField()
sender_avatar = SerializerMethodField()
time = SerializerMethodField()
is_comment = SerializerMethodField()
comment_id = SerializerMethodField()
article_id = SerializerMethodField()
type = CharField(source='msg_type', read_only=True)
extra = CharField(source='extra_info', read_only=True)
link = CharField(source='target_link', read_only=True)
class Meta:
model = Message
fields = [
'id', 'type', 'title', 'content', 'time', 'is_read',
'sender_name', 'sender_avatar', 'extra', 'link',
'is_comment', 'comment_id', 'article_id',
]
async def get_sender_name(self, obj):
sender = await _load_sender(obj)
if sender:
return sender.first_name or sender.username
return '系统'
async def get_sender_avatar(self, obj):
sender = await _load_sender(obj)
if sender and sender.avatar:
request = self.context.get('request')
if request:
return request.build_absolute_uri(sender.avatar.url)
return sender.avatar.url
return ''
async def get_time(self, obj):
return obj.created_at.strftime('%Y-%m-%d %H:%M')
async def get_is_comment(self, obj):
return obj.target_type == 'comment'
async def get_comment_id(self, obj):
if obj.target_type == 'comment' and obj.target_id:
return str(obj.target_id)
return ''
async def get_article_id(self, obj):
if obj.target_link:
import re
match = re.search(r'/article/(\d+)', obj.target_link)
if match:
return match.group(1)
if obj.extra_info:
import re
match = re.search(r'/article/(\d+)', obj.extra_info)
if match:
return match.group(1)
return None
class SystemMessageSerializer(ModelSerializer):
is_read = SerializerMethodField()
class Meta:
model = SystemMessage
fields = ['id', 'title', 'content', 'category', 'icon_name', 'icon_color', 'created_at', 'is_read']
async def get_is_read(self, obj):
read_ids = self.context.get('read_ids', set())
return obj.id in read_ids
class SystemMessageDetailSerializer(ModelSerializer):
is_read = SerializerMethodField()
class Meta:
model = SystemMessage
fields = ['id', 'title', 'content', 'detail', 'category', 'icon_name', 'icon_color', 'created_at', 'is_read']
async def get_is_read(self, obj):
request = self.context.get('request')
if request and request.user.is_authenticated:
return await SystemMessageRead.objects.filter(
user=request.user,
system_message=obj
).aexists()
return False