feat: ADRF async views (phase1) + native async serializers (phase2) + async cache infra
This commit is contained in:
+19
-13
@@ -1,6 +1,7 @@
|
||||
from rest_framework.views import APIView
|
||||
from adrf.views import APIView
|
||||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
from rest_framework import status
|
||||
from asgiref.sync import sync_to_async
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
|
||||
@@ -22,8 +23,8 @@ class QRTokenView(APIView):
|
||||
operation_description='生成唯一的 QR Token,返回 token 供前端生成二维码',
|
||||
responses={200: success_response},
|
||||
)
|
||||
def post(self, request):
|
||||
token = generate_qr_token()
|
||||
async def post(self, request):
|
||||
token = await sync_to_async(generate_qr_token)()
|
||||
return create_standardized_response(data={
|
||||
"token": token,
|
||||
"expires_in": 300,
|
||||
@@ -42,8 +43,9 @@ class QRStatusView(APIView):
|
||||
],
|
||||
responses={200: success_response},
|
||||
)
|
||||
def get(self, request, token):
|
||||
data = get_qr_status(token)
|
||||
async def get(self, request, token):
|
||||
# get_qr_status 走同步 cache,线程池兜底
|
||||
data = await sync_to_async(get_qr_status)(token)
|
||||
response_data = {
|
||||
"status": data.get("status", "expired"),
|
||||
"username": data.get("scan_username"),
|
||||
@@ -51,7 +53,7 @@ class QRStatusView(APIView):
|
||||
|
||||
if data.get("status") == "confirmed":
|
||||
scan_user_id = data.get("scan_user_id")
|
||||
user = FUser.objects.filter(id=scan_user_id).first()
|
||||
user = await FUser.objects.filter(id=scan_user_id).afirst()
|
||||
if user:
|
||||
refresh = RefreshToken.for_user(user)
|
||||
response_data["auth"] = {
|
||||
@@ -81,7 +83,7 @@ class QRScanView(APIView):
|
||||
),
|
||||
responses={200: success_response, 400: error_response, 401: error_response},
|
||||
)
|
||||
def post(self, request):
|
||||
async def post(self, request):
|
||||
token = request.data.get("token")
|
||||
if not token:
|
||||
return create_standardized_error_response(
|
||||
@@ -90,7 +92,8 @@ class QRScanView(APIView):
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
user = request.user
|
||||
success = scan_qr(token, user.id, user.username)
|
||||
# scan_qr 走同步 cache,线程池兜底
|
||||
success = await sync_to_async(scan_qr)(token, user.id, user.username)
|
||||
if not success:
|
||||
return create_standardized_error_response(
|
||||
code=ResponseCode.VALIDATION_ERROR,
|
||||
@@ -116,7 +119,7 @@ class QRConfirmView(APIView):
|
||||
),
|
||||
responses={200: success_response, 400: error_response, 401: error_response},
|
||||
)
|
||||
def post(self, request):
|
||||
async def post(self, request):
|
||||
token = request.data.get("token")
|
||||
if not token:
|
||||
return create_standardized_error_response(
|
||||
@@ -124,14 +127,16 @@ class QRConfirmView(APIView):
|
||||
message="缺少 token",
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
data = confirm_qr(token)
|
||||
# confirm_qr 走同步 cache,线程池兜底
|
||||
data = await sync_to_async(confirm_qr)(token)
|
||||
if not data:
|
||||
return create_standardized_error_response(
|
||||
code=ResponseCode.VALIDATION_ERROR,
|
||||
message="确认失败,请重新扫码",
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
create_login_record(request, request.user, 'success')
|
||||
# create_login_record 内含 ORM 写入,线程池兜底
|
||||
await sync_to_async(create_login_record)(request, request.user, 'success')
|
||||
return create_standardized_response(message="登录确认成功")
|
||||
|
||||
|
||||
@@ -150,8 +155,9 @@ class QRCancelView(APIView):
|
||||
),
|
||||
responses={200: success_response, 401: error_response},
|
||||
)
|
||||
def post(self, request):
|
||||
async def post(self, request):
|
||||
token = request.data.get("token")
|
||||
if token:
|
||||
cancel_qr(token)
|
||||
# cancel_qr 走同步 cache,线程池兜底
|
||||
await sync_to_async(cancel_qr)(token)
|
||||
return create_standardized_response(message="已取消")
|
||||
|
||||
Reference in New Issue
Block a user