ContentNotRenderedError: Содержимое ответа должно быть отображено, прежде чем к нему можно будет получить доступ (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 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 Response(
    data='User is blocked, please contact the support team.',
    status=status.HTTP_403_FORBIDDEN
)

Когда я удаляю промежуточное ПО и не использую класс Response (вместо него возвращается self.get_response(request)), все работает. Я не могу понять причину ошибки. Что я делаю не так?

Если вы возвращаете HttpResponse вместо Response, это работает:

from django.http import HttpResponse

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:
            return HttpResponse('User is blocked due to exceeding throttles limit.', status=403)
        else:
            return response

Вы должны вернуть экземпляр HttpResponse также в вашей реализации handle_blocking, например:

return HttpResponse(
    'User is blocked, please contact the support team.',
    status=403
)
Вернуться на верх