Safely patch additional attributes to Django HttpRequest

Viewed 68

Background

In certain middleware, I want to add some additional attributes to it, like so:

def process_request(self, request: HttpRequest):
    request._additional_info = {}

and then I can access it in the view function:

def update_information(request: HttpRequest) -> HttpResponse:
    if hasattr(request, "_additional_info"):
        request._additional_info["updated"] = True

It works just fine.

However, since _additional_info only presents in runtime, there is no way for mypy to know that it exists, and thus making the hasattr check necessary.

Question

My question is: is it possible to create a class called CustomHttpRequest that behaves exactly the same as HttpRequest except that it explicitly has additional attributes like _additional_info?

Expected Result

With that, I should able to convert HttpRequest to CustomHttpRequest in the middleware, and change the type hints for request in the view functions to CustomHttpRequest.

class ConvertRequests(MiddlewareMixin):
    def __call__(self, request: HttpRequest) -> HttpResponse:
        converted_request = CustomHttpRequest(request)
        return self.get_response(converted_request)

No more hasattr will be needed, and now mypy and autocomplete should know that request may have the attribute _additional_info.

def update_information(request: CustomHttpRequest) -> HttpResponse:
    assert request._additional_info is not None:
    request._additional_info["updated"] = True
0 Answers
Related