feat: ADRF async views (phase1) + native async serializers (phase2) + async cache infra
This commit is contained in:
+48
-30
@@ -1,17 +1,33 @@
|
||||
from rest_framework import serializers
|
||||
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()
|
||||
|
||||
class MessageListSerializer(serializers.ModelSerializer):
|
||||
sender_name = serializers.SerializerMethodField()
|
||||
sender_avatar = serializers.SerializerMethodField()
|
||||
time = serializers.SerializerMethodField()
|
||||
is_comment = serializers.SerializerMethodField()
|
||||
comment_id = serializers.SerializerMethodField()
|
||||
article_id = serializers.SerializerMethodField()
|
||||
type = serializers.CharField(source='msg_type', read_only=True)
|
||||
extra = serializers.CharField(source='extra_info', read_only=True)
|
||||
link = serializers.CharField(source='target_link', read_only=True)
|
||||
|
||||
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
|
||||
@@ -21,31 +37,33 @@ class MessageListSerializer(serializers.ModelSerializer):
|
||||
'is_comment', 'comment_id', 'article_id',
|
||||
]
|
||||
|
||||
def get_sender_name(self, obj):
|
||||
if obj.sender:
|
||||
return obj.sender.nickname or obj.sender.username
|
||||
async def get_sender_name(self, obj):
|
||||
sender = await _load_sender(obj)
|
||||
if sender:
|
||||
return sender.nickname or sender.username
|
||||
return '系统'
|
||||
|
||||
def get_sender_avatar(self, obj):
|
||||
if obj.sender and obj.sender.avatar:
|
||||
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(obj.sender.avatar.url)
|
||||
return obj.sender.avatar.url
|
||||
return request.build_absolute_uri(sender.avatar.url)
|
||||
return sender.avatar.url
|
||||
return ''
|
||||
|
||||
def get_time(self, obj):
|
||||
async def get_time(self, obj):
|
||||
return obj.created_at.strftime('%Y-%m-%d %H:%M')
|
||||
|
||||
def get_is_comment(self, obj):
|
||||
async def get_is_comment(self, obj):
|
||||
return obj.target_type == 'comment'
|
||||
|
||||
def get_comment_id(self, obj):
|
||||
async def get_comment_id(self, obj):
|
||||
if obj.target_type == 'comment' and obj.target_id:
|
||||
return str(obj.target_id)
|
||||
return ''
|
||||
|
||||
def get_article_id(self, obj):
|
||||
async def get_article_id(self, obj):
|
||||
if obj.target_link:
|
||||
import re
|
||||
match = re.search(r'/article/(\d+)', obj.target_link)
|
||||
@@ -59,30 +77,30 @@ class MessageListSerializer(serializers.ModelSerializer):
|
||||
return None
|
||||
|
||||
|
||||
class SystemMessageSerializer(serializers.ModelSerializer):
|
||||
is_read = serializers.SerializerMethodField()
|
||||
class SystemMessageSerializer(ModelSerializer):
|
||||
is_read = SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = SystemMessage
|
||||
fields = ['id', 'title', 'content', 'category', 'icon_name', 'icon_color', 'created_at', 'is_read']
|
||||
|
||||
def get_is_read(self, obj):
|
||||
async def get_is_read(self, obj):
|
||||
read_ids = self.context.get('read_ids', set())
|
||||
return obj.id in read_ids
|
||||
|
||||
|
||||
class SystemMessageDetailSerializer(serializers.ModelSerializer):
|
||||
is_read = serializers.SerializerMethodField()
|
||||
class SystemMessageDetailSerializer(ModelSerializer):
|
||||
is_read = SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = SystemMessage
|
||||
fields = ['id', 'title', 'content', 'detail', 'category', 'icon_name', 'icon_color', 'created_at', 'is_read']
|
||||
|
||||
def get_is_read(self, obj):
|
||||
async def get_is_read(self, obj):
|
||||
request = self.context.get('request')
|
||||
if request and request.user.is_authenticated:
|
||||
return SystemMessageRead.objects.filter(
|
||||
return await SystemMessageRead.objects.filter(
|
||||
user=request.user,
|
||||
system_message=obj
|
||||
).exists()
|
||||
).aexists()
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user