ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Django 异步视图的 adrf 解决办法

Django 异步视图的 adrf 解决办法 在 Django 编写异步视图时可能会遇到以下错误AssertionError: Expected a Response, HttpResponse or HttpStreamingResponse to be returned from the viewTypeError: sync_to_async can only be applied to sync functions.这些错误通常发生在async def视图方法中Django 默认的APIView不能直接支持异步处理导致返回值类型不符合 DRF 规范或者异步方法的调用方式错误。示例如下importasynciofromrest_framework.responseimportResponsefromrest_framework.viewsimportAPIViewfromrest_framework.permissionsimportAllowAnyclassNewView(APIView):permission_classes[AllowAny]asyncdefpost(self,request,*args,**kwargs):# 异步操作模拟resultawaitself.long_running_task()returnResponse({message:result})asyncdeflong_running_task(self):# 模拟一个耗时的异步任务awaitasyncio.sleep(2)returnCompleted long-running task在这种情况下Django 无法正确解析async def视图方法的返回值导致AssertionError。此外如果试图使用sync_to_async处理同步函数可能会因错误的函数类型应用而触发TypeError。解决方案要解决该问题需要使用adrfAsynchronous Django REST Framework它扩展了 DRF允许异步视图方法的正确执行。首先需要安装adrfpipinstalladrf然后修改视图使其继承自adrf提供的APIView避免与 DRF 原有的APIView冲突这里重命名为adrfAPIViewimportasynciofromrest_framework.responseimportResponsefromrest_framework.permissionsimportAllowAnyfromadrf.viewsimportAPIViewasadrfAPIViewclassNewView(adrfAPIView):permission_classes[AllowAny]asyncdefpost(self,request,*args,**kwargs):# 异步操作模拟resultawaitself.long_running_task()returnResponse({message:result})asyncdeflong_running_task(self):# 模拟一个耗时的异步任务awaitasyncio.sleep(2)returnCompleted long-running taskDjango 默认的APIView仅支持同步视图方法因此不能直接使用async def否则会导致返回值解析错误。而adrf提供了对async def视图的完整支持使得post方法可以正确执行异步任务。在post方法中调用了await self.long_running_task()该方法模拟了一个耗时的异步任务2 秒延迟。当任务完成后返回一个 JSON 响应通知客户端任务已完成。使用cURL或 Postman 发送POST请求curl-XPOST http://localhost:8000/newview/服务器正确响应{message:Completed long-running task}在 Django 编写异步视图时需要确保所继承的视图基类支持异步方法否则会出现AssertionError或TypeError。使用adrf可以让 DRF 兼容async def视图提高性能特别适用于 I/O 密集型任务如数据库查询、HTTP 请求或文件操作等场景。
返回列表