找个地方重写APIViewdispatch方法,示例:
    apps.common.views.AAPIView

    1. from asgiref.sync import sync_to_async
    2. from rest_framework.views import APIView
    3. class AAPIView(APIView):
    4. """
    5. Async ApiView
    6. @see
    7. https://github.com/encode/django-rest-framework/pull/8617/commits/79ce07ba9b0d46cb7c0c592ef47e7f834f651df4#diff-b750fc158f144a0a00aab378a20b42038ed6c59f4b80f533331f3c682e76cb06R2
    8. https://github.com/em1208/adrf
    9. """
    10. async def async_dispatch(self, request, *args, **kwargs):
    11. self.args = args
    12. self.kwargs = kwargs
    13. request = self.initialize_request(request, *args, **kwargs)
    14. self.request = request
    15. self.headers = self.default_response_headers # deprecate?
    16. try:
    17. await sync_to_async(self.initial)(request, *args, **kwargs)
    18. # Get the appropriate handler method
    19. if request.method.lower() in self.http_method_names:
    20. handler = getattr(self, request.method.lower(),
    21. self.http_method_not_allowed)
    22. else:
    23. handler = self.http_method_not_allowed
    24. response = await handler(request, *args, **kwargs)
    25. except Exception as exc:
    26. response = self.handle_exception(exc)
    27. self.response = self.finalize_response(request, response, *args, **kwargs)
    28. return self.response
    29. def dispatch(self, request, *args, **kwargs):
    30. return self.async_dispatch(request, *args, **kwargs)

    在正式使用时,在原有的继承中,额外继承Async APIVIew,示例:
    apps.target_manager.views

    1. from asgiref.sync import sync_to_async
    2. import time
    3. from rest_framework import generics
    4. from rest_framework.response import Response
    5. from apps.common.views import AAPIView
    6. from . import serializers as target_serializers
    7. async def test_sleep():
    8. await sync_to_async(time.sleep, thread_sensitive=False)(5)
    9. print('helloworld')
    10. class TargetBaseInfoView(generics.CreateAPIView, AAPIView):
    11. serializer_class = target_serializers.DemoSerializer
    12. async def post(self, request, *args, **kwargs):
    13. asyncio.create_task(test_sleep())
    14. return Response({'method': 'POST'})

    apps.target_manager.serializers

    1. from rest_framework import serializers
    2. class DemoSerializer(serializers.Serializer):
    3. urls = serializers.ListField(help_text='待扫描的URL列表')

    image.png
    将数据处理逻辑放在序列化层

    1. from asgiref.sync import sync_to_async
    2. import asyncio
    3. import time
    4. from rest_framework import serializers
    5. async def test_sleep():
    6. await sync_to_async(time.sleep, thread_sensitive=False)(5)
    7. print('helloworld')
    8. class DemoSerializer(serializers.Serializer):
    9. urls = serializers.ListField(
    10. child=serializers.CharField(),
    11. help_text='待扫描的URL列表'
    12. )
    13. def create(self, validated_data):
    14. asyncio.create_task(test_sleep())
    15. return validated_data
    1. from rest_framework import generics
    2. from . import serializers as target_serializers
    3. from apps.common.views import AAPIView
    4. from rest_framework.response import Response
    5. class TargetBaseInfoView(generics.ListCreateAPIView, AAPIView):
    6. serializer_class = target_serializers.DemoSerializer
    7. async def get(self, request, *args, **kwargs):
    8. return Response({'method': 'GET'})
    9. async def post(self, request, *args, **kwargs):
    10. return super().post(request, *args, **kwargs)