From 0f3491850b0070d5ef22369c14c1cb577ca0cd66 Mon Sep 17 00:00:00 2001 From: TheSteveBurgess <79967988+TheSteveBurgess@users.noreply.github.com> Date: Wed, 1 May 2024 16:01:09 +0100 Subject: [PATCH] feat: Support both sync and async in ComponentDependencyMiddleware Co-authored-by: TheSteveBurgess --- src/django_components/middleware.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/django_components/middleware.py b/src/django_components/middleware.py index 72f42270..44fc32e8 100644 --- a/src/django_components/middleware.py +++ b/src/django_components/middleware.py @@ -2,10 +2,12 @@ import re from collections.abc import Callable from typing import TYPE_CHECKING, Iterable +from asgiref.sync import iscoroutinefunction, markcoroutinefunction from django.conf import settings from django.forms import Media from django.http import HttpRequest, HttpResponse, StreamingHttpResponse from django.http.response import HttpResponseBase +from django.utils.decorators import sync_and_async_middleware from django_components.component_registry import registry @@ -25,6 +27,7 @@ PLACEHOLDER_REGEX = re.compile( ) +@sync_and_async_middleware class ComponentDependencyMiddleware: """Middleware that inserts CSS/JS dependencies for all rendered components at points marked with template tags.""" @@ -33,14 +36,32 @@ class ComponentDependencyMiddleware: def __init__(self, get_response: "Callable[[HttpRequest], HttpResponse]") -> None: self.get_response = get_response + if iscoroutinefunction(self.get_response): + markcoroutinefunction(self) + def __call__(self, request: HttpRequest) -> HttpResponseBase: + + if iscoroutinefunction(self): + return self.__acall__(request) + response = self.get_response(request) + response = self.process_response(response) + return response + + async def __acall__(self, request: HttpRequest) -> HttpResponseBase: + + response = await self.get_response(request) + response = self.process_response(response) + return response + + def process_response(self, response: HttpResponse) -> HttpResponse: if ( getattr(settings, "COMPONENTS", {}).get("RENDER_DEPENDENCIES", False) and not isinstance(response, StreamingHttpResponse) and response.get("Content-Type", "").startswith("text/html") ): response.content = process_response_content(response.content) + return response