You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django升级至3.2.8后结合Channels与OpenCensus中间件出现500错误:TypeError: object HttpResponse can't be used in 'await' expression

搞定Django 3.2 + Channels + OpenCensus中间件触发的500错误

先拆解问题根源

从你贴的错误日志里,两个核心异常已经把问题点得明明白白了:

  • AttributeError: 'coroutine' object has no attribute 'get':Clickjacking中间件想调用response.get()来处理X-Frame-Options头,但此时的response居然是个协程对象,不是正常的HttpResponse
  • TypeError: object HttpResponse can't be used in 'await' expression:ASGI的异步处理链在等待一个协程结果,却拿到了同步的HttpResponse对象

本质原因就是同步实现的OpenCensus中间件,在Django 3.2的ASGI异步处理流程中水土不服。Django 3.2对ASGI的中间件执行逻辑做了优化,当用Channels当ASGI服务器时,HTTP请求走的是异步处理链,而同步中间件没做适配的话,会直接打乱响应的类型流转,导致后续环节拿到完全不符合预期的对象。

给你几个可行的解决方案

方案1:把OpenCensus中间件包装成异步兼容版

Django自带的SyncToAsync工具可以帮我们把同步中间件转换成异步兼容的。你可以这么做:

  1. 在项目根目录新建一个middleware.py文件,写个包装器:
from asgiref.sync import SyncToAsync
from opencensus.ext.django.middleware import OpencensusMiddleware

class AsyncOpencensusMiddleware:
    def __init__(self, get_response):
        self.sync_middleware = OpencensusMiddleware(get_response)
        self.get_response = get_response

    async def __call__(self, request):
        # 把同步的请求前置处理转成异步执行
        await SyncToAsync(self.sync_middleware.process_request)(request)
        # 继续走后续中间件/视图的异步流程
        response = await self.get_response(request)
        # 把同步的响应后置处理转成异步执行
        response = await SyncToAsync(self.sync_middleware.process_response)(request, response)
        return response
  1. 然后修改settings.py里的MIDDLEWARE列表,把原来的OpenCensus中间件替换成我们写的异步版本:
MIDDLEWARE = [
    # ... 其他中间件保持不动
    'testproject.middleware.AsyncOpencensusMiddleware'  # 这里换成你项目的实际路径
]

方案2:调整ASGI配置,给HTTP请求加同步适配包装

你也可以直接修改asgi.py,给Django的ASGI应用套一层SyncToAsync,确保同步中间件能正常工作:

import os
from django.core.asgi import get_asgi_application
from asgiref.sync import SyncToAsync
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import testproject.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testproject.settings')

application = ProtocolTypeRouter({
    # 给HTTP请求的ASGI应用加同步适配
    "http": SyncToAsync(get_asgi_application()),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            testproject.routing.websocket_urlpatterns
        )
    ),
})

方案3:升级OpenCensus到最新版本

有可能是你用的opencensus-ext-django版本太老,没适配Django 3.2的ASGI环境。先试试升级:

pip install --upgrade opencensus-ext-django

如果升级后还是不行,那大概率是OpenCensus的中间件本身存在ASGI兼容性bug,你可以去他们的仓库提交issue,把你的场景(Django3.2+Channels+同步中间件)描述清楚。

验证方法

  1. 随便选一个方案改完后,重启Daphne服务器
  2. 访问http://127.0.0.1:8000/,看看是不是能正常返回响应了
  3. 再看日志,确认之前那两个异常消失了就行

内容的提问来源于stack exchange,提问作者Oscar Hermoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:13:10