feat: ADRF async views (phase1) + native async serializers (phase2) + async cache infra
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
from django.http import JsonResponse
|
||||
from rest_framework.views import APIView
|
||||
from adrf.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.parsers import JSONParser
|
||||
from django.db import transaction
|
||||
from asgiref.sync import sync_to_async
|
||||
from ..models import Tool, ToolFavorite
|
||||
|
||||
|
||||
@@ -10,60 +10,75 @@ class ToolFavoriteToggleView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@transaction.atomic
|
||||
def post(self, request, tool_id):
|
||||
try:
|
||||
tool = Tool.objects.get(pk=tool_id, is_enabled=True)
|
||||
except Tool.DoesNotExist:
|
||||
async def post(self, request, tool_id):
|
||||
# 事务段(get_or_create + delete + count)整体放入同步函数,sync_to_async 执行保证原子性
|
||||
def _toggle_in_txn():
|
||||
from django.db import transaction
|
||||
with transaction.atomic():
|
||||
try:
|
||||
tool = Tool.objects.get(pk=tool_id, is_enabled=True)
|
||||
except Tool.DoesNotExist:
|
||||
return None
|
||||
favorite, created = ToolFavorite.objects.get_or_create(
|
||||
user=request.user,
|
||||
tool=tool
|
||||
)
|
||||
if not created:
|
||||
favorite.delete()
|
||||
is_favorite = False
|
||||
message = '已取消收藏'
|
||||
else:
|
||||
is_favorite = True
|
||||
message = '已添加收藏'
|
||||
favorite_count = ToolFavorite.objects.filter(tool=tool).count()
|
||||
return {
|
||||
'tool_id': tool.id,
|
||||
'is_favorite': is_favorite,
|
||||
'favorite_count': favorite_count,
|
||||
'message': message,
|
||||
}
|
||||
|
||||
result = await sync_to_async(_toggle_in_txn)()
|
||||
if result is None:
|
||||
return JsonResponse({'success': False, 'error': '工具不存在'}, status=404)
|
||||
|
||||
favorite, created = ToolFavorite.objects.get_or_create(
|
||||
user=request.user,
|
||||
tool=tool
|
||||
)
|
||||
if not created:
|
||||
favorite.delete()
|
||||
is_favorite = False
|
||||
message = '已取消收藏'
|
||||
else:
|
||||
is_favorite = True
|
||||
message = '已添加收藏'
|
||||
|
||||
favorite_count = ToolFavorite.objects.filter(tool=tool).count()
|
||||
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
'data': {
|
||||
'id': tool.id,
|
||||
'is_favorite': is_favorite,
|
||||
'favorite_count': favorite_count
|
||||
'id': result['tool_id'],
|
||||
'is_favorite': result['is_favorite'],
|
||||
'favorite_count': result['favorite_count']
|
||||
},
|
||||
'message': message
|
||||
'message': result['message']
|
||||
})
|
||||
|
||||
|
||||
class ToolFavoriteListView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request):
|
||||
favorites = ToolFavorite.objects.select_related('tool', 'tool__category').filter(
|
||||
async def get(self, request):
|
||||
favorites = [fav async for fav in ToolFavorite.objects.select_related(
|
||||
'tool', 'tool__category'
|
||||
).filter(
|
||||
user=request.user,
|
||||
tool__is_enabled=True
|
||||
).order_by('-created_at')
|
||||
).order_by('-created_at')]
|
||||
|
||||
data = [{
|
||||
'id': fav.tool.id,
|
||||
'name': fav.tool.name,
|
||||
'description': fav.tool.description,
|
||||
'icon': fav.tool.icon,
|
||||
'url_path': fav.tool.url_path,
|
||||
'color': fav.tool.color,
|
||||
'category': fav.tool.category.id if fav.tool.category else None,
|
||||
'category_name': fav.tool.category.name if fav.tool.category else '',
|
||||
'is_favorite': True,
|
||||
'favorite_count': ToolFavorite.objects.filter(tool=fav.tool).count(),
|
||||
'created_at': fav.created_at.isoformat()
|
||||
} for fav in favorites]
|
||||
data = []
|
||||
for fav in favorites:
|
||||
favorite_count = await ToolFavorite.objects.filter(tool=fav.tool).acount()
|
||||
data.append({
|
||||
'id': fav.tool.id,
|
||||
'name': fav.tool.name,
|
||||
'description': fav.tool.description,
|
||||
'icon': fav.tool.icon,
|
||||
'url_path': fav.tool.url_path,
|
||||
'color': fav.tool.color,
|
||||
'category': fav.tool.category.id if fav.tool.category else None,
|
||||
'category_name': fav.tool.category.name if fav.tool.category else '',
|
||||
'is_favorite': True,
|
||||
'favorite_count': favorite_count,
|
||||
'created_at': fav.created_at.isoformat()
|
||||
})
|
||||
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
@@ -77,13 +92,13 @@ class ToolFavoriteListView(APIView):
|
||||
class ToolFavoriteStatusView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, tool_id):
|
||||
is_favorite = ToolFavorite.objects.filter(
|
||||
async def get(self, request, tool_id):
|
||||
is_favorite = await ToolFavorite.objects.filter(
|
||||
user=request.user,
|
||||
tool_id=tool_id
|
||||
).exists()
|
||||
).aexists()
|
||||
|
||||
favorite_count = ToolFavorite.objects.filter(tool_id=tool_id).count()
|
||||
favorite_count = await ToolFavorite.objects.filter(tool_id=tool_id).acount()
|
||||
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
|
||||
Reference in New Issue
Block a user