Skip to content

Commit c3d9832

Browse files
committed
added decorator for functions
1 parent cd750ab commit c3d9832

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

django_replicated/decorators.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,29 @@ def my_view(request, ...):
2121

2222
from django.utils.decorators import decorator_from_middleware_with_args
2323

24+
from .utils import routers
2425
from .middleware import ReplicationMiddleware
2526

2627

28+
def use_state_in_function(forced_state='master'):
29+
30+
def _make_decorator(func):
31+
32+
def wrapper():
33+
prev_state = routers.state() # Store previous state
34+
routers.init(forced_state) # Set state to the forced_state
35+
func()
36+
# If previous state was master, set it back
37+
# Handling function calls from other functions or classes
38+
if prev_state == 'master':
39+
routers.init('master')
40+
return wrapper
41+
42+
return _make_decorator
43+
44+
2745
use_state = decorator_from_middleware_with_args(ReplicationMiddleware)
2846
use_master = use_state(forced_state='master')
2947
use_slave = use_state(forced_state='slave')
48+
use_master_in_function = use_state_in_function()
49+
use_slave_in_function = use_state_in_function(forced_state='slave')

django_replicated/middleware.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def check_state_override(self, request, state):
105105
Used to check if a web request should use a master or slave
106106
database besides default choice.
107107
'''
108-
if request.COOKIES.get(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME) == 'true':
108+
if getattr(request, 'COOKIES', {}).get(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME) == 'true':
109109
return 'master'
110110

111111
override_state = self.get_state_override(request)
@@ -150,7 +150,7 @@ def handle_redirect_after_write(self, request, response):
150150
log.debug('set force master cookie for %s', request.path)
151151
self.set_force_master_cookie(response)
152152
else:
153-
if settings.REPLICATED_FORCE_MASTER_COOKIE_NAME in request.COOKIES:
153+
if settings.REPLICATED_FORCE_MASTER_COOKIE_NAME in getattr(request, 'COOKIES', {}):
154154
response.delete_cookie(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME)
155155

156156
def set_force_master_cookie(self, response):

django_replicated/router.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ def db_for_write(self, *args, **kwargs):
7777
if self.CHECK_STATE_ON_WRITE and self.state() != 'master':
7878
raise RuntimeError('Trying to access master database in slave state')
7979

80+
if self.state() != 'master':
81+
self.use_state('master')
82+
8083
self.context.chosen['master'] = self.DEFAULT_DB_ALIAS
8184

8285
log.debug('db_for_write: %s', self.DEFAULT_DB_ALIAS)

tests/test_decorators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django.test import RequestFactory
44
from django.http import HttpResponse
55

6-
from django_replicated.decorators import use_state
6+
from django_replicated.decorators import use_state, use_state_in_function
77
from django_replicated.utils import routers
88

99

0 commit comments

Comments
 (0)