feat: ADRF async views (phase1) + native async serializers (phase2) + async cache infra
This commit is contained in:
@@ -1,29 +1,29 @@
|
||||
from rest_framework import serializers
|
||||
from adrf.serializers import ModelSerializer
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from .models import BrowsingHistory
|
||||
|
||||
|
||||
class BrowsingHistorySerializer(serializers.ModelSerializer):
|
||||
class BrowsingHistorySerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = BrowsingHistory
|
||||
fields = ['id', 'type', 'title', 'description', 'image', 'category', 'link', 'viewed_at']
|
||||
read_only_fields = ['viewed_at']
|
||||
|
||||
|
||||
class BrowsingHistoryCreateSerializer(serializers.ModelSerializer):
|
||||
class BrowsingHistoryCreateSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = BrowsingHistory
|
||||
fields = ['type', 'title', 'description', 'image', 'category', 'link']
|
||||
|
||||
def create(self, validated_data):
|
||||
async def acreate(self, validated_data):
|
||||
user = self.context['request'].user
|
||||
link = validated_data.get('link', '')
|
||||
today = timezone.now().date()
|
||||
existing = BrowsingHistory.objects.filter(
|
||||
existing = await BrowsingHistory.objects.filter(
|
||||
user=user, link=link, viewed_at__date=today
|
||||
).first()
|
||||
).afirst()
|
||||
if existing:
|
||||
existing.save()
|
||||
await existing.asave()
|
||||
return existing
|
||||
return BrowsingHistory.objects.create(user=user, **validated_data)
|
||||
return await BrowsingHistory.objects.acreate(user=user, **validated_data)
|
||||
|
||||
+21
-14
@@ -1,14 +1,17 @@
|
||||
from rest_framework import generics, status
|
||||
from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.views import APIView
|
||||
from adrf.views import APIView
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.response import Response
|
||||
from django.shortcuts import get_object_or_404
|
||||
from asgiref.sync import sync_to_async
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
from chunyu_project.common_schemas import success_response, error_response, unauthorized_response, not_found_response
|
||||
|
||||
from adrf import generics
|
||||
from adrf.generics import aget_object_or_404
|
||||
|
||||
from utils.response_codes import ResponseCode, create_standardized_response, create_standardized_error_response
|
||||
from .models import BrowsingHistory
|
||||
from .serializers import BrowsingHistorySerializer, BrowsingHistoryCreateSerializer
|
||||
@@ -62,13 +65,15 @@ class BrowsingHistoryListCreateView(generics.ListCreateAPIView):
|
||||
],
|
||||
responses={200: success_response, 401: unauthorized_response}
|
||||
)
|
||||
def list(self, request, *args, **kwargs):
|
||||
async def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
page = self.paginate_queryset(queryset)
|
||||
# 兜底:DRF 分页器内部同步评估 queryset(count + 切片取值)
|
||||
page = await sync_to_async(self.paginate_queryset)(queryset)
|
||||
if page is not None:
|
||||
serializer = self.get_serializer(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
results = [x async for x in queryset]
|
||||
serializer = self.get_serializer(results, many=True)
|
||||
return Response({'code': 10000, 'message': 'Success', 'data': serializer.data})
|
||||
|
||||
@swagger_auto_schema(
|
||||
@@ -78,10 +83,12 @@ class BrowsingHistoryListCreateView(generics.ListCreateAPIView):
|
||||
request_body=BrowsingHistoryCreateSerializer,
|
||||
responses={201: success_response, 400: error_response, 401: unauthorized_response}
|
||||
)
|
||||
def create(self, request, *args, **kwargs):
|
||||
async def create(self, request, *args, **kwargs):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
instance = serializer.save()
|
||||
is_valid = await sync_to_async(serializer.is_valid)()
|
||||
if is_valid:
|
||||
# 兜底:serializer.create 内部有同步 ORM(filter/first/save/create)
|
||||
instance = await sync_to_async(serializer.save)()
|
||||
return create_standardized_response(
|
||||
data=BrowsingHistorySerializer(instance).data,
|
||||
code=ResponseCode.SUCCESS,
|
||||
@@ -107,9 +114,9 @@ class BrowsingHistoryDeleteView(APIView):
|
||||
],
|
||||
responses={204: '删除成功', 401: unauthorized_response, 404: not_found_response}
|
||||
)
|
||||
def delete(self, request, pk):
|
||||
record = get_object_or_404(BrowsingHistory, pk=pk, user=request.user)
|
||||
record.delete()
|
||||
async def delete(self, request, pk):
|
||||
record = await aget_object_or_404(BrowsingHistory, pk=pk, user=request.user)
|
||||
await record.adelete()
|
||||
return create_standardized_response(
|
||||
code=ResponseCode.SUCCESS,
|
||||
message='删除成功',
|
||||
@@ -126,8 +133,8 @@ class BrowsingHistoryClearView(APIView):
|
||||
operation_description='清空当前用户的所有浏览历史记录',
|
||||
responses={200: success_response, 401: unauthorized_response}
|
||||
)
|
||||
def delete(self, request):
|
||||
count = BrowsingHistory.objects.filter(user=request.user).delete()[0]
|
||||
async def delete(self, request):
|
||||
count = (await BrowsingHistory.objects.filter(user=request.user).adelete())[0]
|
||||
return create_standardized_response(
|
||||
data={'deleted': count},
|
||||
code=ResponseCode.SUCCESS,
|
||||
|
||||
Reference in New Issue
Block a user