ContentNotRenderedError: The response content must be rendered before it can be accessed (Django Middleware)
ContentNotRenderedError: The response content must be rendered before it can be accessed (Django Middleware)
我正在创建 Django 中间件,用于在用户被限制超过 5 次时阻止用户,但我得到 ContentNotRenderedError
。
完整错误消息:
Traceback (most recent call last):
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/utils/deprecation.py", line 119, in __call__
response = self.process_response(request, response)
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/middleware/common.py", line 113, in process_response
response.headers['Content-Length'] = str(len(response.content))
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/template/response.py", line 126, in content
raise ContentNotRenderedError(
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be accessed.
[22/Mar/2022 11:55:03] "GET /api/v1/userdetail/ HTTP/1.1" 500 84321
中间件class
class BlockMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# some other variables
def __call__(self, request):
# handle_blocking will return "None" if user can access application else "rest_framework.response.Response" object
blocking_res = self.handle_blocking(request)
if blocking_res:
return blocking_res
response = self.get_response(request)
# logic for counting how many throttles have left
# then
if throttles_left <= 0:
return Response(
data='User is blocked due to exceeding throttles limit.',
status=status.HTTP_403_FORBIDDEN
)
else:
return response
handle_blocking
函数的 return 示例:
return Response(
data='User is blocked, please contact the support team.',
status=status.HTTP_403_FORBIDDEN
)
当我删除中间件并且不使用 Response
class(return 而不是 self.get_response(request) 时,它会起作用。
我无法找出错误。我做错了什么?
如果你真的想要 return 一个 Response
实例,你需要在 return 之前设置一些属性:
from rest_framework.renderers import JSONRenderer
class BlockMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
blocking_res = self.handle_blocking(request)
if blocking_res:
return blocking_res
response = self.get_response(request)
if throttles_left <= 0:
response = Response(
data='User is blocked due to exceeding throttles limit.',
status=status.HTTP_403_FORBIDDEN
)
response.accepted_renderer = JSONRenderer()
response.accepted_media_type = "application/json"
response.renderer_context = {}
response.render()
return response
else:
return response
您也需要在 handle_blocking
实施中执行相同的操作,例如:
from rest_framework.renderers import JSONRenderer
response = Response(
data='User is blocked, please contact the support team.',
status=status.HTTP_403_FORBIDDEN
)
response.accepted_renderer = JSONRenderer()
response.accepted_media_type = "application/json"
response.renderer_context = {}
response.render()
return response
这些属性一般由api_view
装饰器设置,不能与中间件一起使用,所以必须手动设置。
我正在创建 Django 中间件,用于在用户被限制超过 5 次时阻止用户,但我得到 ContentNotRenderedError
。
完整错误消息:
Traceback (most recent call last):
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/utils/deprecation.py", line 119, in __call__
response = self.process_response(request, response)
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/middleware/common.py", line 113, in process_response
response.headers['Content-Length'] = str(len(response.content))
File "/home/raptor/Application/utilities/anaconda3/envs/slic4rapi/lib/python3.8/site-packages/django/template/response.py", line 126, in content
raise ContentNotRenderedError(
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be accessed.
[22/Mar/2022 11:55:03] "GET /api/v1/userdetail/ HTTP/1.1" 500 84321
中间件class
class BlockMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# some other variables
def __call__(self, request):
# handle_blocking will return "None" if user can access application else "rest_framework.response.Response" object
blocking_res = self.handle_blocking(request)
if blocking_res:
return blocking_res
response = self.get_response(request)
# logic for counting how many throttles have left
# then
if throttles_left <= 0:
return Response(
data='User is blocked due to exceeding throttles limit.',
status=status.HTTP_403_FORBIDDEN
)
else:
return response
handle_blocking
函数的 return 示例:
return Response(
data='User is blocked, please contact the support team.',
status=status.HTTP_403_FORBIDDEN
)
当我删除中间件并且不使用 Response
class(return 而不是 self.get_response(request) 时,它会起作用。
我无法找出错误。我做错了什么?
如果你真的想要 return 一个 Response
实例,你需要在 return 之前设置一些属性:
from rest_framework.renderers import JSONRenderer
class BlockMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
blocking_res = self.handle_blocking(request)
if blocking_res:
return blocking_res
response = self.get_response(request)
if throttles_left <= 0:
response = Response(
data='User is blocked due to exceeding throttles limit.',
status=status.HTTP_403_FORBIDDEN
)
response.accepted_renderer = JSONRenderer()
response.accepted_media_type = "application/json"
response.renderer_context = {}
response.render()
return response
else:
return response
您也需要在 handle_blocking
实施中执行相同的操作,例如:
from rest_framework.renderers import JSONRenderer
response = Response(
data='User is blocked, please contact the support team.',
status=status.HTTP_403_FORBIDDEN
)
response.accepted_renderer = JSONRenderer()
response.accepted_media_type = "application/json"
response.renderer_context = {}
response.render()
return response
这些属性一般由api_view
装饰器设置,不能与中间件一起使用,所以必须手动设置。