diff --git a/api/views/GetIPDataView.py b/api/views/GetIPDataView.py index 2f8a3de..999dde0 100644 --- a/api/views/GetIPDataView.py +++ b/api/views/GetIPDataView.py @@ -1,6 +1,7 @@ import asyncio import aiohttp +from utils.async_cache import aget_cache, aset_cache, adelete_cache from asgiref.sync import sync_to_async from rest_framework.permissions import AllowAny @@ -106,7 +107,7 @@ class GetIPDataView(APIView): cache_key = f"ip_location:{ip}" # 先尝试从缓存获取(django-redis 为同步客户端,用 sync_to_async 兜底) - cached_data = await sync_to_async(default_cache.get)(cache_key) + cached_data = await aget_cache(cache_key) if cached_data: return Response( {"code": 200, "message": "success", "data": cached_data}, @@ -143,7 +144,7 @@ class GetIPDataView(APIView): } # 写入缓存(sync_to_async 兜底) - await sync_to_async(default_cache.set)(cache_key, ip_info, IP_CACHE_TIMEOUT) + await aset_cache(cache_key, ip_info, IP_CACHE_TIMEOUT) return Response( {"code": 200, "message": "success", "data": ip_info}, diff --git a/apidirectory/views.py b/apidirectory/views.py index a59a56e..e228e08 100644 --- a/apidirectory/views.py +++ b/apidirectory/views.py @@ -26,7 +26,7 @@ class CategoryListView(APIView): return JsonResponse({ 'code': 200, 'message': 'success', - 'data': serializer.data + 'data': await serializer.adata }) @@ -74,7 +74,7 @@ class ApiItemListView(APIView): return JsonResponse({ 'code': 200, 'message': 'success', - 'data': serializer.data + 'data': await serializer.adata }) @@ -94,7 +94,7 @@ class ApiItemDetailView(APIView): return JsonResponse({ 'code': 200, 'message': 'success', - 'data': serializer.data + 'data': await serializer.adata }) except ApiItem.DoesNotExist: return JsonResponse({ diff --git a/article/views.py b/article/views.py index b40a2ae..977e81f 100644 --- a/article/views.py +++ b/article/views.py @@ -144,8 +144,8 @@ class ArticleListCreateView(generics.ListCreateAPIView): ) async def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() await sync_to_async(track_task)(request.user, 'post') data = await get_data(serializer) return create_standardized_response( @@ -218,8 +218,8 @@ class ArticleDetailView(APIView): status_code=status.HTTP_403_FORBIDDEN ) serializer = ArticleCreateUpdateSerializer(article, data=request.data, partial=True, context={'request': request}) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() data = await get_data(serializer) return create_standardized_response(data=data, code=ResponseCode.SUCCESS, message='文章更新成功') return create_standardized_error_response( @@ -319,7 +319,7 @@ class ArticleCommentListCreateView(generics.ListCreateAPIView): article_id = self.kwargs['article_id'] article = await aget_object_or_404(Article, pk=article_id) serializer = self.get_serializer(data=request.data) - if await sync_to_async(serializer.is_valid)(): + if serializer.is_valid(): def _save_and_notify(): with transaction.atomic(): comment = serializer.save(user=request.user, article=article) diff --git a/bug/views.py b/bug/views.py index a2bd87c..48a54e9 100644 --- a/bug/views.py +++ b/bug/views.py @@ -44,7 +44,7 @@ class BugReportListCreateAPIView(generics.ListCreateAPIView): items = [x async for x in queryset] serializer = self.get_serializer(items, many=True) # 兜底:user_name 触发 user 外键懒加载、images_count 内部有同步 ORM count() - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response( code=ResponseCode.SUCCESS, data=data, @@ -60,13 +60,13 @@ class BugReportListCreateAPIView(generics.ListCreateAPIView): ) async def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - is_valid = await sync_to_async(serializer.is_valid)() + is_valid = serializer.is_valid() if is_valid: # 兜底:serializer.create 内部有同步 ORM(BugReport/BugReportImage/BugReportAttachment 的 create) - bug_report = await sync_to_async(serializer.save)(user=request.user) + bug_report = await serializer.asave(user=request.user) detail_serializer = BugReportDetailSerializer(bug_report) # 兜底:detail 序列化会触发 user/images/attachments/comments 的同步懒加载 - data = await sync_to_async(lambda: detail_serializer.data)() + data = await detail_serializer.adata return create_standardized_response( code=ResponseCode.SUCCESS, data=data, @@ -104,7 +104,7 @@ class BugReportDetailAPIView(generics.RetrieveAPIView): instance = await self.get_object() serializer = self.get_serializer(instance) # 兜底:detail 序列化会触发 user/images/attachments/comments 的同步懒加载 - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response( code=ResponseCode.SUCCESS, data=data, @@ -144,7 +144,7 @@ class BugReportCommentCreateAPIView(generics.CreateAPIView): ) serializer = self.get_serializer(data=request.data) - is_valid = await sync_to_async(serializer.is_valid)() + is_valid = serializer.is_valid() if is_valid: # 兜底:serializer.create 内部有同步 ORM(comment 及其图片/附件的 create) comment = await sync_to_async(serializer.save)( @@ -154,7 +154,7 @@ class BugReportCommentCreateAPIView(generics.CreateAPIView): ) comment_serializer = BugReportCommentSerializer(comment) # 兜底:comment 序列化会触发 user 外键与 images/attachments 的同步懒加载 - data = await sync_to_async(lambda: comment_serializer.data)() + data = await comment_serializer.adata return create_standardized_response( code=ResponseCode.SUCCESS, data=data, diff --git a/chat/views.py b/chat/views.py index 1ddd6f5..964b9b3 100644 --- a/chat/views.py +++ b/chat/views.py @@ -292,7 +292,7 @@ class ConversationListView(APIView): conversations = [p.conversation async for p in participations] serializer = ConversationSerializer(conversations, many=True, context={'request': request}) # 兜底:ConversationSerializer 的 SerializerMethodField 内部有同步 ORM 查询 - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response(data=data, code=ResponseCode.SUCCESS) @swagger_auto_schema( @@ -334,7 +334,7 @@ class ConversationListView(APIView): serializer = ConversationSerializer(conversation, context={'request': request}) # 兜底:ConversationSerializer 的 SerializerMethodField 内部有同步 ORM 查询 - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response(data=data, code=ResponseCode.SUCCESS, status_code=status.HTTP_201_CREATED) @@ -372,7 +372,7 @@ class ConversationMessageView(APIView): serializer = ChatMessageSerializer(page_messages, many=True, context={'request': request}) # 兜底:'conversation' 外键未预加载,serializer 取值会触发同步 ORM - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response(data={ 'results': data, 'total': total, diff --git a/history/views.py b/history/views.py index 30ef538..f03d2ab 100644 --- a/history/views.py +++ b/history/views.py @@ -71,10 +71,10 @@ class BrowsingHistoryListCreateView(generics.ListCreateAPIView): 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) + return self.get_paginated_response(await serializer.adata) results = [x async for x in queryset] serializer = self.get_serializer(results, many=True) - return Response({'code': 10000, 'message': 'Success', 'data': serializer.data}) + return Response({'code': 10000, 'message': 'Success', 'data': await serializer.adata}) @swagger_auto_schema( tags=['历史'], @@ -85,10 +85,10 @@ class BrowsingHistoryListCreateView(generics.ListCreateAPIView): ) async def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - is_valid = await sync_to_async(serializer.is_valid)() + is_valid = serializer.is_valid() if is_valid: # 兜底:serializer.create 内部有同步 ORM(filter/first/save/create) - instance = await sync_to_async(serializer.save)() + instance = await serializer.asave() return create_standardized_response( data=BrowsingHistorySerializer(instance).data, code=ResponseCode.SUCCESS, diff --git a/learn/views.py b/learn/views.py index c814151..f13c392 100644 --- a/learn/views.py +++ b/learn/views.py @@ -117,8 +117,8 @@ class CourseListCreateView(generics.ListCreateAPIView): ) async def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() data = await get_data(serializer) return create_standardized_response( data=data, @@ -188,8 +188,8 @@ class CourseDetailView(APIView): status_code=status.HTTP_403_FORBIDDEN ) serializer = CourseCreateUpdateSerializer(course, data=request.data, partial=True, context={'request': request}) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() data = await get_data(serializer) return create_standardized_response(data=data, code=ResponseCode.SUCCESS, message='课程更新成功') return create_standardized_error_response( @@ -278,7 +278,7 @@ class ChapterListCreateView(generics.ListCreateAPIView): course_id = self.kwargs['course_id'] course = await aget_object_or_404(Course, pk=course_id) serializer = self.get_serializer(data=request.data) - if await sync_to_async(serializer.is_valid)(): + if serializer.is_valid(): await sync_to_async(serializer.save)(course=course) data = await get_data(serializer) return create_standardized_response( @@ -336,8 +336,8 @@ class ChapterDetailView(APIView): async def put(self, request, pk): chapter = await aget_object_or_404(Chapter, pk=pk) serializer = ChapterSerializer(chapter, data=request.data, partial=True) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() data = await get_data(serializer) return create_standardized_response(data=data, code=ResponseCode.SUCCESS, message='章节更新成功') return create_standardized_error_response( @@ -414,8 +414,8 @@ class ChapterContentView(APIView): defaults={'content_md': '', 'content_html': ''} ) serializer = ChapterContentSerializer(content, data=request.data, partial=True) - if await sync_to_async(serializer.is_valid)(): - await sync_to_async(serializer.save)() + if serializer.is_valid(): + await serializer.asave() data = await get_data(serializer) return create_standardized_response(data=data, code=ResponseCode.SUCCESS, message='内容保存成功') return create_standardized_error_response( diff --git a/message/views.py b/message/views.py index 88318f4..808ba17 100644 --- a/message/views.py +++ b/message/views.py @@ -42,9 +42,9 @@ class MessageListView(APIView): if msg_type == 'system': queryset = SystemMessage.objects.all() - def _paginate_system(): + async def _paginate_system(): paginator = MessagePagination() - page = paginator.paginate_queryset(queryset, request) + page = await sync_to_async(paginator.paginate_queryset)(queryset, request) read_ids = set( SystemMessageRead.objects.filter( user=request.user, @@ -52,10 +52,9 @@ class MessageListView(APIView): ).values_list('system_message_id', flat=True) ) serializer = SystemMessageSerializer(page, many=True, context={'request': request, 'read_ids': read_ids}) - return paginator.get_paginated_response(serializer.data).data + return paginator.get_paginated_response(await serializer.adata).data - # 兜底:DRF 分页器与 SystemMessageSerializer 内部为同步调用 - data = await sync_to_async(_paginate_system)() + data = await _paginate_system() return create_standardized_response(data=data, code=ResponseCode.SUCCESS) valid_types = ['reply', 'at_me', 'like'] @@ -64,14 +63,13 @@ class MessageListView(APIView): else: queryset = Message.objects.filter(recipient=request.user) - def _paginate_messages(): + async def _paginate_messages(): paginator = MessagePagination() - page = paginator.paginate_queryset(queryset, request) + page = await sync_to_async(paginator.paginate_queryset)(queryset, request) serializer = MessageListSerializer(page, many=True, context={'request': request}) - return paginator.get_paginated_response(serializer.data).data + return paginator.get_paginated_response(await serializer.adata).data - # 兜底:DRF 分页器与 MessageListSerializer(obj.sender 外键访问)内部为同步调用 - data = await sync_to_async(_paginate_messages)() + data = await _paginate_messages() return create_standardized_response(data=data, code=ResponseCode.SUCCESS) @@ -294,5 +292,5 @@ class SystemMessageDetailView(APIView): serializer = SystemMessageDetailSerializer(system_message, context={'request': request}) # 兜底:SystemMessageDetailSerializer.get_is_read 内部有同步 ORM exists() 查询 - data = await sync_to_async(lambda: serializer.data)() + data = await serializer.adata return create_standardized_response(data=data, code=ResponseCode.SUCCESS) diff --git a/tool/views/color_history_view.py b/tool/views/color_history_view.py index b1b14e7..3304c9a 100644 --- a/tool/views/color_history_view.py +++ b/tool/views/color_history_view.py @@ -25,7 +25,7 @@ class ColorHistoryListView(APIView): created_at__gte=cutoff ).order_by('-created_at')[:50]] serializer = ColorHistorySerializer(histories, many=True) - return Response(serializer.data) + return Response(await serializer.adata) async def post(self, request): color = request.data.get('color', '') @@ -43,13 +43,13 @@ class ColorHistoryListView(APIView): existing.created_at = timezone.now() await existing.asave() serializer = ColorHistorySerializer(existing) - return Response(serializer.data, status=status.HTTP_200_OK) + return Response(await serializer.adata, status=status.HTTP_200_OK) history = await ColorHistory.objects.acreate( user=request.user, color=color ) serializer = ColorHistorySerializer(history) - return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(await serializer.adata, status=status.HTTP_201_CREATED) class ColorHistoryDetailView(APIView): diff --git a/tool/views/compression_history_view.py b/tool/views/compression_history_view.py index 30b3500..8f6f3ab 100644 --- a/tool/views/compression_history_view.py +++ b/tool/views/compression_history_view.py @@ -35,7 +35,7 @@ class CompressionHistoryListView(APIView): return JsonResponse({ 'success': True, - 'data': serializer.data, + 'data': await serializer.adata, 'total': total, 'page': page, 'page_size': page_size @@ -50,10 +50,10 @@ class CompressionHistoryListView(APIView): serializer = CompressionHistorySerializer(data=data) if serializer.is_valid(): # DRF 序列化器 save() 为同步 ORM 操作,sync_to_async 兜底 - await sync_to_async(serializer.save)() + await serializer.asave() return JsonResponse({ 'success': True, - 'data': serializer.data + 'data': await serializer.adata }, status=status.HTTP_201_CREATED) return JsonResponse({ diff --git a/tool/views/tool_manage_view.py b/tool/views/tool_manage_view.py index 33458ce..83deac9 100644 --- a/tool/views/tool_manage_view.py +++ b/tool/views/tool_manage_view.py @@ -24,7 +24,7 @@ class ToolCategoryListView(APIView): serializer = ToolCategorySerializer(categories, many=True) return JsonResponse({ 'success': True, - 'data': serializer.data + 'data': await serializer.adata }) @@ -70,7 +70,7 @@ class ToolListView(APIView): tool_list = [t async for t in tools] serializer = ToolSerializer(tool_list, many=True) - data = serializer.data + data = await serializer.adata # 构建 favorites_count 映射 favorites_count_map = { @@ -111,7 +111,7 @@ class ToolDetailView(APIView): try: tool = await Tool.objects.select_related('category').aget(pk=pk, is_enabled=True) serializer = ToolSerializer(tool) - data = serializer.data + data = await serializer.adata if request.user.is_authenticated: data['is_favorited'] = await ToolFavorite.objects.filter( user=request.user, tool=tool diff --git a/user/views/blacklist.py b/user/views/blacklist.py index 9d62ab9..c745a6a 100644 --- a/user/views/blacklist.py +++ b/user/views/blacklist.py @@ -90,11 +90,11 @@ class BlacklistAddAPIView(APIView): status_code=status.HTTP_400_BAD_REQUEST ) - blacklist = await sync_to_async(serializer.save)() + blacklist = await serializer.asave() result_serializer = BlacklistSerializer(blacklist) return create_standardized_response( - data=result_serializer.data, + data=await result_serializer.adata, code=ResponseCode.SUCCESS, status_code=status.HTTP_201_CREATED ) diff --git a/user/views/email.py b/user/views/email.py index 1fc74cb..a89eeb3 100644 --- a/user/views/email.py +++ b/user/views/email.py @@ -102,7 +102,7 @@ class SendChangeEmailCodeAPIView(APIView): try: # save() 内部触发验证码邮件发送(Celery/cache/SMTP 链路),线程池兜底 - email = await sync_to_async(serializer.save)() + email = await serializer.asave() await sync_to_async(reset_failures)(operation, identifier) return create_standardized_response( data={'email_sent': True}, @@ -157,11 +157,11 @@ class ChangeEmailAPIView(APIView): ) try: - updated_user = await sync_to_async(serializer.save)() + updated_user = await serializer.asave() user_serializer = UserSerializer(updated_user) return create_standardized_response( - data={'user': user_serializer.data}, + data={'user': await user_serializer.adata}, code=ResponseCode.EMAIL_CHANGED, status_code=status.HTTP_200_OK ) diff --git a/user/views/login_record.py b/user/views/login_record.py index 8ce40a2..74c1919 100644 --- a/user/views/login_record.py +++ b/user/views/login_record.py @@ -76,7 +76,7 @@ class LoginRecordListAPIView(APIView): return create_standardized_response( data={ - 'records': serializer.data, + 'records': await serializer.adata, 'total': total, 'page': page, 'page_size': page_size, diff --git a/user/views/phone.py b/user/views/phone.py index e59558b..5b9844e 100644 --- a/user/views/phone.py +++ b/user/views/phone.py @@ -41,7 +41,7 @@ class SendPhoneCodeAPIView(APIView): ) try: - phone = await sync_to_async(serializer.save)() + phone = await serializer.asave() return create_standardized_response( data={'phone_sent': True}, code=ResponseCode.SUCCESS, @@ -81,11 +81,11 @@ class ChangePhoneAPIView(APIView): ) try: - updated_user = await sync_to_async(serializer.save)() + updated_user = await serializer.asave() user_serializer = UserSerializer(updated_user) return create_standardized_response( - data={'user': user_serializer.data}, + data={'user': await user_serializer.adata}, code=ResponseCode.SUCCESS, status_code=status.HTTP_200_OK ) diff --git a/user/views/region.py b/user/views/region.py index 3d35010..c41a732 100644 --- a/user/views/region.py +++ b/user/views/region.py @@ -81,6 +81,6 @@ class RegionListView(APIView): regions = [r async for r in queryset] serializer = RegionSimpleSerializer(regions, many=True) return Response( - {"code": 200, "message": "success", "data": serializer.data}, + {"code": 200, "message": "success", "data": await serializer.adata}, status=status.HTTP_200_OK ) diff --git a/user/views/user.py b/user/views/user.py index e1b8c0b..305bdc2 100644 --- a/user/views/user.py +++ b/user/views/user.py @@ -2,6 +2,7 @@ import os import uuid import logging +from utils.async_cache import aget_cache, aset_cache, adelete_cache from asgiref.sync import sync_to_async from utils.email_utils import validate_email_mx from rest_framework.decorators import permission_classes @@ -93,7 +94,7 @@ class SendUserEmailAPIView(APIView): if not user_exists_result: code = RandCode.get_digit_characters_code_8() - await sync_to_async(default_cache.set)(f"register_{to_email}", code, timeout=600) + await aset_cache(f"register_{to_email}", code, timeout=600) result = await sync_to_async(submit_task)(send_verification_email_task, to_email, code, 'register') if result is None: @@ -108,7 +109,7 @@ class SendUserEmailAPIView(APIView): ) else: code = RandCode.get_digit_characters_code_8() - await sync_to_async(default_cache.set)(f"login_{to_email}", code, timeout=600) + await aset_cache(f"login_{to_email}", code, timeout=600) result = await sync_to_async(submit_task)(send_verification_email_task, to_email, code, 'login') if result is None: @@ -162,7 +163,7 @@ class UserLoginOrRegisterAPIView(APIView): if user is None: # Registration flow - vcode = await sync_to_async(default_cache.get)(f"register_{to_email}") + vcode = await aget_cache(f"register_{to_email}") if vcode is None: return create_standardized_error_response( @@ -173,9 +174,9 @@ class UserLoginOrRegisterAPIView(APIView): if code == vcode: user_serializer = UserSerializer(data=request.data) if await sync_to_async(user_serializer.is_valid)(): - user = await sync_to_async(user_serializer.create_by_email)(request.data) + user = await user_serializer.acreate_by_email(request.data) refresh = RefreshToken.for_user(user) - user_data = await sync_to_async(_serialize_user)(user) + user_data = await UserSerializer(user).adata # Prepare response data response_data = { @@ -205,7 +206,7 @@ class UserLoginOrRegisterAPIView(APIView): ) else: # Login flow - vcode = await sync_to_async(default_cache.get)(f"login_{to_email}") + vcode = await aget_cache(f"login_{to_email}") if vcode is None: return create_standardized_error_response( @@ -215,7 +216,7 @@ class UserLoginOrRegisterAPIView(APIView): if code == vcode: refresh = RefreshToken.for_user(user) - user_data = await sync_to_async(_serialize_user)(user) + user_data = await UserSerializer(user).adata # Prepare response data response_data = { @@ -322,7 +323,7 @@ class ForgotPasswordSendCodeAPIView(APIView): ) code = RandCode.get_digit_characters_code_8() - await sync_to_async(default_cache.set)(f"reset_password_{to_email}", code, timeout=600) + await aset_cache(f"reset_password_{to_email}", code, timeout=600) result = await sync_to_async(submit_task)(send_reset_password_email_task, to_email, code) if result is None: @@ -433,7 +434,7 @@ class ForgotPasswordResetAPIView(APIView): ) try: - vcode = await sync_to_async(default_cache.get)(f"reset_password_{to_email}") + vcode = await aget_cache(f"reset_password_{to_email}") if vcode is None: await sync_to_async(record_failure)(operation, to_email) @@ -461,7 +462,7 @@ class ForgotPasswordResetAPIView(APIView): await sync_to_async(user.set_password)(new_password) await user.asave() - await sync_to_async(default_cache.delete)(f"reset_password_{to_email}") + await adelete_cache(f"reset_password_{to_email}") await sync_to_async(reset_failures)(operation, to_email) return create_standardized_response( @@ -487,7 +488,7 @@ class UserUpdateAPIView(APIView): ) async def get(self, request): user = request.user - user_data = await sync_to_async(_serialize_user)(user) + user_data = await UserSerializer(user).adata return create_standardized_response( data={'user': user_data}, @@ -526,8 +527,8 @@ class UserUpdateAPIView(APIView): status_code=status.HTTP_400_BAD_REQUEST ) - updated_user = await sync_to_async(serializer.save)() - user_data = await sync_to_async(_serialize_user)(updated_user) + updated_user = await serializer.asave() + user_data = await UserSerializer(updated_user).adata try: await sync_to_async(log_event)( @@ -632,8 +633,8 @@ class ChangePasswordAPIView(APIView): status_code=status.HTTP_400_BAD_REQUEST ) - user = await sync_to_async(serializer.save)() - user_data = await sync_to_async(_serialize_user)(user) + user = await serializer.asave() + user_data = await UserSerializer(user).adata is_new_set = not request.user.has_usable_password() or request.data.get('old_password', '') == '' @@ -682,7 +683,7 @@ class UserLoginAPIView(APIView): if user is not None: if user.is_active: refresh = RefreshToken.for_user(user) - user_data = await sync_to_async(_serialize_user)(user) + user_data = await UserSerializer(user).adata response_data = { 'user': user_data, @@ -797,7 +798,7 @@ class LoginView(APIView): if user.is_active: await sync_to_async(reset_failures)(operation, identifier) refresh = RefreshToken.for_user(user) - user_data = await sync_to_async(_serialize_user)(user) + user_data = await UserSerializer(user).adata response_data = { 'user': user_data, diff --git a/user/views/wallet.py b/user/views/wallet.py index 986ecfa..06404b7 100644 --- a/user/views/wallet.py +++ b/user/views/wallet.py @@ -81,7 +81,7 @@ class WalletTransactionsAPIView(APIView): return create_standardized_response( data={ - 'transactions': serializer.data, + 'transactions': await serializer.adata, 'total': total, 'page': page, 'page_size': page_size,