Skip to content

Commit 61df0e2

Browse files
john-partonpre-commit-ci[bot]ddabble
authored
Use sync/async pattern for middleware since Django 3.1 (#1209)
* Sync and async middleware. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated changelog for #1209 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Anders <6058745+ddabble@users.noreply.github.com>
1 parent 2e3e325 commit 61df0e2

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Unreleased
1818
- Made ``bulk_update_with_history()`` return the number of model rows updated (gh-1206)
1919
- Fixed ``HistoryRequestMiddleware`` not cleaning up after itself (i.e. deleting
2020
``HistoricalRecords.context.request``) under some circumstances (gh-1188)
21+
- Made ``HistoryRequestMiddleware`` async-capable (gh-1209)
2122

2223
3.3.0 (2023-03-08)
2324
------------------

simple_history/middleware.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
1+
from contextlib import contextmanager
2+
3+
from asgiref.sync import iscoroutinefunction
4+
from django.utils.decorators import sync_and_async_middleware
5+
16
from .models import HistoricalRecords
27

38

4-
class HistoryRequestMiddleware:
9+
@contextmanager
10+
def _context_manager(request):
11+
HistoricalRecords.context.request = request
12+
13+
try:
14+
yield None
15+
finally:
16+
del HistoricalRecords.context.request
17+
18+
19+
@sync_and_async_middleware
20+
def HistoryRequestMiddleware(get_response):
521
"""Expose request to HistoricalRecords.
622
723
This middleware sets request as a local context/thread variable, making it
824
available to the model-level utilities to allow tracking of the authenticated user
925
making a change.
1026
"""
1127

12-
def __init__(self, get_response):
13-
self.get_response = get_response
14-
15-
def __call__(self, request):
16-
HistoricalRecords.context.request = request
17-
try:
18-
response = self.get_response(request)
19-
except Exception as e:
20-
raise e
21-
finally:
22-
del HistoricalRecords.context.request
23-
return response
28+
if iscoroutinefunction(get_response):
29+
30+
async def middleware(request):
31+
with _context_manager(request):
32+
return await get_response(request)
33+
34+
else:
35+
36+
def middleware(request):
37+
with _context_manager(request):
38+
return get_response(request)
39+
40+
return middleware

0 commit comments

Comments
 (0)