Coverage for apis_core/generic/middleware.py: 36%

22 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-09-15 06:01 +0000

1""" 

2Copyright (c) 2023 Benoit Blanchon 

3License: MIT 

4 

5This is copied from https://github.com/bblanchon/django-htmx-messages-framework 

6Commit a2da4176ac4a53fb0d7f42e8a1de398e4e5f9c1c 

7""" 

8 

9import json 

10 

11from django.contrib.messages import get_messages 

12from django.http import HttpRequest, HttpResponse 

13from django.utils.deprecation import MiddlewareMixin 

14 

15 

16class HtmxMessageMiddleware(MiddlewareMixin): 

17 """ 

18 Middleware that moves messages into the HX-Trigger header when request is made with HTMX 

19 """ 

20 

21 def process_response( 

22 self, request: HttpRequest, response: HttpResponse 

23 ) -> HttpResponse: 

24 # The HX-Request header indicates that the request was made with HTMX 

25 if "HX-Request" not in request.headers: 

26 return response 

27 

28 # Ignore redirections because HTMX cannot read the headers 

29 if 300 <= response.status_code < 400: 

30 return response 

31 

32 # Extract the messages 

33 messages = [ 

34 {"message": message.message, "tags": message.tags} 

35 for message in get_messages(request) 

36 ] 

37 if not messages: 

38 return response 

39 

40 # Get the existing HX-Trigger that could have been defined by the view 

41 hx_trigger = response.headers.get("HX-Trigger") 

42 

43 if hx_trigger is None: 

44 # If the HX-Trigger is not set, start with an empty object 

45 hx_trigger = {} 

46 elif hx_trigger.startswith("{"): 

47 # If the HX-Trigger uses the object syntax, parse the object 

48 hx_trigger = json.loads(hx_trigger) 

49 else: 

50 # If the HX-Trigger uses the string syntax, convert to the object syntax 

51 hx_trigger = {hx_trigger: True} 

52 

53 # Add the messages array in the HX-Trigger object 

54 hx_trigger["messages"] = messages 

55 

56 # Add or update the HX-Trigger 

57 response.headers["HX-Trigger"] = json.dumps(hx_trigger) 

58 

59 return response