Django 4.2异步调用模型对象后如何访问其属性与方法?
Django 4.2异步调用模型对象的问题排查与解决
错误原因分析与修复
1. 多余await引发的第一个错误
get_module_object是异步函数,用await调用后会直接返回ProjectModule实例或HttpResponseServerError响应对象,不是协程对象。你额外写的module = await module_coroutine属于重复await非协程对象,这是错误根源。
修复代码:
# 错误写法 module_coroutine = await get_module_object(module_id=module_id) module = await module_coroutine # 此行完全多余 # 正确写法 module = await get_module_object(module_id=module_id) # 先判断是否为异常响应,直接返回 if isinstance(module, HttpResponseServerError): return module
2. 未定义变量+多余await引发的第二个错误
你在await call_url(...)后写了response = await response_coroutine,但response_coroutine从未定义,属于笔误;同时aiohttp.ClientResponse.text()是异步方法,必须用await调用才能获取文本内容。
修复代码:
# 错误写法 response = await call_url(url=module.url) response = await response_coroutine # 无定义变量,且多余 # 正确写法 response = await call_url(url=module.url) # 处理异常响应 if isinstance(response, web.Response): return HttpResponseServerError("调用外部URL失败") # 异步读取响应文本 response_text = await response.text() soup = BeautifulSoup(response_text, "lxml")
3. PyCharm自动补全失效问题
因为get_module_object的返回类型不明确(可能是ProjectModule或HttpResponseServerError),IDE无法推断module的具体类型,导致无法提供自动补全。解决方法是添加类型注解,并在调用后通过类型判断或断言明确类型。
修改get_module_object的类型注解:
from django.http import HttpResponseServerError from typing import Union async def get_module_object(module_id: int) -> Union[ProjectModule, HttpResponseServerError]: """Get module object.""" try: return await ProjectModule.objects.aget(pk=module_id) except Exception as e: return HttpResponseServerError(f"Error: {e}")
调用时添加类型断言:
module = await get_module_object(module_id=module_id) if isinstance(module, HttpResponseServerError): return module # 告诉IDE此时module是ProjectModule实例 module = cast(ProjectModule, module)
完整修复后的htmx_test_run_module函数
from typing import cast from bs4 import BeautifulSoup from django.http import HttpResponse, HttpResponseServerError import aiohttp from aiohttp import web async def htmx_test_run_module(request, module_id: int): """Test run module with HTMX request.""" if request.method == "GET": try: module = await get_module_object(module_id=module_id) if isinstance(module, HttpResponseServerError): return module module = cast(ProjectModule, module) response = await call_url(url=module.url) if isinstance(response, web.Response): return HttpResponseServerError("调用外部URL失败") response_text = await response.text() soup = BeautifulSoup(response_text, "lxml") tag = soup.find( module.container_html_tag, class_=module.container_html_tag_class ) return HttpResponse(str(tag) if tag else "未找到指定标签") except Exception as e: return HttpResponseServerError(f"Error: {e}")
内容的提问来源于stack exchange,提问作者Vitalii Mytenko
相关产品推荐
相关产品推荐

