Skip to content

Commit 9c26625

Browse files
iamanikeevRoss Mechanic
authored andcommitted
Backward compatible middleware (#403)
* Roll back middleware class so that it supports old style middleware * More reasonable comment for middleware setting * Use different middleware styles in tests for Django 2.0 and previous versions * Roll back middleware class so that it supports old style middleware * More reasonable comment for middleware setting * Use different middleware styles in tests for Django 2.0 and previous versions * Rename variable to fit into line length
1 parent 84f5e2a commit 9c26625

File tree

7 files changed

+41
-43
lines changed

7 files changed

+41
-43
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Authors
5959
- Ray Logel
6060
- Nathan Villagaray-Carski
6161
- Mike Spainhower
62+
- Alexander Anikeev
6263

6364
Background
6465
==========

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Unreleased
77
- Add ability to specify custom history_id field (gh-368)
88
- Add HistoricalRecord instance properties `prev_record` and `next_record` (gh-365)
99
- Can set admin methods as attributes on object history change list template (gh-390)
10+
- Fixed compatibility of >= 2.0 versions with old-style middleware (gh-369)
1011

1112
2.0 (2018-04-05)
1213
----------------

runtests.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@
3939
'ENGINE': 'django.db.backends.sqlite3',
4040
}
4141
},
42-
MIDDLEWARE=[
43-
'django.contrib.sessions.middleware.SessionMiddleware',
44-
'django.contrib.auth.middleware.AuthenticationMiddleware',
45-
'django.contrib.messages.middleware.MessageMiddleware',
46-
],
4742
TEMPLATES=[{
4843
'BACKEND': 'django.template.backends.django.DjangoTemplates',
4944
'APP_DIRS': True,
@@ -54,6 +49,16 @@
5449
},
5550
}],
5651
)
52+
MIDDLEWARE = [
53+
'django.contrib.sessions.middleware.SessionMiddleware',
54+
'django.contrib.auth.middleware.AuthenticationMiddleware',
55+
'django.contrib.messages.middleware.MessageMiddleware',
56+
]
57+
58+
if django.__version__ >= '2.0':
59+
DEFAULT_SETTINGS['MIDDLEWARE'] = MIDDLEWARE
60+
else:
61+
DEFAULT_SETTINGS['MIDDLEWARE_CLASSES'] = MIDDLEWARE
5762

5863

5964
def main():

simple_history/middleware.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
1+
from django.utils.deprecation import MiddlewareMixin
2+
13
from .models import HistoricalRecords
24

35

4-
class HistoryRequestMiddleware:
6+
class HistoryRequestMiddleware(MiddlewareMixin):
57
"""Expose request to HistoricalRecords.
68
79
This middleware sets request as a local thread variable, making it
810
available to the model-level utilities to allow tracking of the
911
authenticated user making a change.
1012
"""
1113

12-
def __init__(self, get_response):
13-
self.get_response = get_response
14-
15-
def __call__(self, request):
16-
# Code to be executed for each request before
17-
# the view (and later middleware) are called.
18-
14+
def process_request(self, request):
1915
HistoricalRecords.thread.request = request
2016

21-
response = self.get_response(request)
22-
23-
# Code to be executed for each request/response after
24-
# the view is called.
25-
17+
def process_response(self, request, response):
2618
if hasattr(HistoricalRecords.thread, 'request'):
2719
del HistoricalRecords.thread.request
28-
2920
return response

simple_history/tests/tests/test_admin.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from datetime import datetime, timedelta
22

3-
from django.conf import settings
43
from django.contrib.admin import AdminSite
54
from django.contrib.admin.utils import quote
65
from django.contrib.auth import get_user_model
@@ -14,6 +13,7 @@
1413

1514
from simple_history.admin import SimpleHistoryAdmin
1615
from simple_history.models import HistoricalRecords
16+
from simple_history.tests.tests.utils import middleware_override_settings
1717
from ..models import (
1818
Book,
1919
Choice,
@@ -45,12 +45,6 @@ def get_history_url(obj, history_index=None, site="admin"):
4545
site=site, app=app, model=model), args=[quote(obj.pk)])
4646

4747

48-
overridden_settings = {
49-
'MIDDLEWARE': (settings.MIDDLEWARE +
50-
['simple_history.middleware.HistoryRequestMiddleware']),
51-
}
52-
53-
5448
class AdminSiteTest(WebTest):
5549
def setUp(self):
5650
self.user = User.objects.create_superuser('user_login',
@@ -231,7 +225,7 @@ def test_history_user_not_saved(self):
231225
"No way to know of request, history_user should be unset.",
232226
)
233227

234-
@override_settings(**overridden_settings)
228+
@override_settings(**middleware_override_settings)
235229
def test_middleware_saves_user(self):
236230
self.login()
237231
form = self.app.get(reverse('admin:tests_book_add')).form
@@ -244,13 +238,13 @@ def test_middleware_saves_user(self):
244238
"Middleware should make the request available to "
245239
"retrieve history_user.")
246240

247-
@override_settings(**overridden_settings)
241+
@override_settings(**middleware_override_settings)
248242
def test_middleware_unsets_request(self):
249243
self.login()
250244
self.app.get(reverse('admin:tests_book_add'))
251245
self.assertFalse(hasattr(HistoricalRecords.thread, 'request'))
252246

253-
@override_settings(**overridden_settings)
247+
@override_settings(**middleware_override_settings)
254248
def test_rolled_back_user_does_not_lead_to_foreign_key_error(self):
255249
# This test simulates the rollback of a user after a request (which
256250
# happens, e.g. in test cases), and verifies that subsequently
@@ -270,7 +264,7 @@ def test_rolled_back_user_does_not_lead_to_foreign_key_error(self):
270264
"No way to know of request, history_user should be unset.",
271265
)
272266

273-
@override_settings(**overridden_settings)
267+
@override_settings(**middleware_override_settings)
274268
def test_middleware_anonymous_user(self):
275269
self.app.get(reverse('admin:index'))
276270
poll = Poll.objects.create(question="why?", pub_date=today)

simple_history/tests/tests/test_middleware.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
from datetime import date
22

3-
from django.conf import settings
43
from django.test import TestCase, override_settings
54
from django.urls import reverse
65

76
from simple_history.tests.custom_user.models import CustomUser
87
from simple_history.tests.models import Poll
9-
10-
overridden_settings = {
11-
'MIDDLEWARE': (settings.MIDDLEWARE +
12-
['simple_history.middleware.HistoryRequestMiddleware']),
13-
}
8+
from simple_history.tests.tests.utils import middleware_override_settings
149

1510

11+
@override_settings(**middleware_override_settings)
1612
class MiddlewareTest(TestCase):
1713
def setUp(self):
1814
self.user = CustomUser.objects.create_superuser(
@@ -21,7 +17,6 @@ def setUp(self):
2117
'pass'
2218
)
2319

24-
@override_settings(**overridden_settings)
2520
def test_user_is_set_on_create_view_when_logged_in(self):
2621
self.client.force_login(self.user)
2722
data = {
@@ -37,7 +32,6 @@ def test_user_is_set_on_create_view_when_logged_in(self):
3732
self.assertListEqual([ph.history_user_id for ph in poll_history],
3833
[self.user.id])
3934

40-
@override_settings(**overridden_settings)
4135
def test_user_is_not_set_on_create_view_not_logged_in(self):
4236
data = {
4337
'question': 'Test question',
@@ -52,7 +46,6 @@ def test_user_is_not_set_on_create_view_not_logged_in(self):
5246
self.assertListEqual([ph.history_user_id for ph in poll_history],
5347
[None])
5448

55-
@override_settings(**overridden_settings)
5649
def test_user_is_set_on_update_view_when_logged_in(self):
5750
self.client.force_login(self.user)
5851
poll = Poll.objects.create(
@@ -76,7 +69,6 @@ def test_user_is_set_on_update_view_when_logged_in(self):
7669
self.assertListEqual([ph.history_user_id for ph in poll_history],
7770
[self.user.id, None])
7871

79-
@override_settings(**overridden_settings)
8072
def test_user_is_not_set_on_update_view_when_not_logged_in(self):
8173
poll = Poll.objects.create(
8274
question='Test question',
@@ -99,7 +91,6 @@ def test_user_is_not_set_on_update_view_when_not_logged_in(self):
9991
self.assertListEqual([ph.history_user_id for ph in poll_history],
10092
[None, None])
10193

102-
@override_settings(**overridden_settings)
10394
def test_user_is_unset_on_update_view_after_logging_out(self):
10495
self.client.force_login(self.user)
10596
poll = Poll.objects.create(
@@ -137,7 +128,6 @@ def test_user_is_unset_on_update_view_after_logging_out(self):
137128
self.assertListEqual([ph.history_user_id for ph in poll_history],
138129
[None, self.user.id, None])
139130

140-
@override_settings(**overridden_settings)
141131
def test_user_is_set_on_delete_view_when_logged_in(self):
142132
self.client.force_login(self.user)
143133
poll = Poll.objects.create(
@@ -155,7 +145,6 @@ def test_user_is_set_on_delete_view_when_logged_in(self):
155145
self.assertListEqual([ph.history_user_id for ph in poll_history],
156146
[self.user.id, None])
157147

158-
@override_settings(**overridden_settings)
159148
def test_user_is_not_set_on_delete_view_when_not_logged_in(self):
160149
poll = Poll.objects.create(
161150
question='Test question',

simple_history/tests/tests/utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import django
2+
from django.conf import settings
3+
4+
request_middleware = 'simple_history.middleware.HistoryRequestMiddleware'
5+
6+
if django.__version__ >= '2.0':
7+
middleware_override_settings = {
8+
'MIDDLEWARE': (
9+
settings.MIDDLEWARE + [request_middleware]
10+
)
11+
}
12+
else:
13+
middleware_override_settings = {
14+
'MIDDLEWARE_CLASSES': (
15+
settings.MIDDLEWARE_CLASSES + [request_middleware]
16+
)
17+
}

0 commit comments

Comments
 (0)