From 9856e2579962eea317490101207d59add7e4fbff Mon Sep 17 00:00:00 2001 From: Varun Bargali Date: Tue, 2 Jul 2019 20:51:41 +0530 Subject: [PATCH 1/4] added decorator for functions --- django_replicated/decorators.py | 20 ++++++++++++++++++++ django_replicated/middleware.py | 4 ++-- django_replicated/router.py | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/django_replicated/decorators.py b/django_replicated/decorators.py index 2e13d40..82c2b5b 100644 --- a/django_replicated/decorators.py +++ b/django_replicated/decorators.py @@ -21,9 +21,29 @@ def my_view(request, ...): from django.utils.decorators import decorator_from_middleware_with_args +from .utils import routers from .middleware import ReplicationMiddleware +def use_state_in_function(forced_state='master'): + + def _make_decorator(func): + + def wrapper(): + prev_state = routers.state() # Store previous state + routers.init(forced_state) # Set state to the forced_state + func() + # If previous state was master, set it back + # Handling function calls from other functions or classes + if prev_state == 'master': + routers.init('master') + return wrapper + + return _make_decorator + + use_state = decorator_from_middleware_with_args(ReplicationMiddleware) use_master = use_state(forced_state='master') use_slave = use_state(forced_state='slave') +use_master_in_function = use_state_in_function() +use_slave_in_function = use_state_in_function(forced_state='slave') diff --git a/django_replicated/middleware.py b/django_replicated/middleware.py index 9c4f011..6379021 100644 --- a/django_replicated/middleware.py +++ b/django_replicated/middleware.py @@ -105,7 +105,7 @@ def check_state_override(self, request, state): Used to check if a web request should use a master or slave database besides default choice. ''' - if request.COOKIES.get(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME) == 'true': + if getattr(request, 'COOKIES', {}).get(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME) == 'true': return 'master' override_state = self.get_state_override(request) @@ -150,7 +150,7 @@ def handle_redirect_after_write(self, request, response): log.debug('set force master cookie for %s', request.path) self.set_force_master_cookie(response) else: - if settings.REPLICATED_FORCE_MASTER_COOKIE_NAME in request.COOKIES: + if settings.REPLICATED_FORCE_MASTER_COOKIE_NAME in getattr(request, 'COOKIES', {}): response.delete_cookie(settings.REPLICATED_FORCE_MASTER_COOKIE_NAME) def set_force_master_cookie(self, response): diff --git a/django_replicated/router.py b/django_replicated/router.py index a8e16c2..db4d667 100644 --- a/django_replicated/router.py +++ b/django_replicated/router.py @@ -77,6 +77,9 @@ def db_for_write(self, *args, **kwargs): if self.CHECK_STATE_ON_WRITE and self.state() != 'master': raise RuntimeError('Trying to access master database in slave state') + if self.state() != 'master': + self.use_state('master') + self.context.chosen['master'] = self.DEFAULT_DB_ALIAS log.debug('db_for_write: %s', self.DEFAULT_DB_ALIAS) From 1b5f2b2980fa39fa6b0ac78172d628a9b8e24df6 Mon Sep 17 00:00:00 2001 From: Varun Bargali Date: Fri, 5 Jul 2019 02:18:04 +0530 Subject: [PATCH 2/4] minor fix in router. --- django_replicated/router.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_replicated/router.py b/django_replicated/router.py index db4d667..0e921c8 100644 --- a/django_replicated/router.py +++ b/django_replicated/router.py @@ -78,7 +78,7 @@ def db_for_write(self, *args, **kwargs): raise RuntimeError('Trying to access master database in slave state') if self.state() != 'master': - self.use_state('master') + self.init('master') self.context.chosen['master'] = self.DEFAULT_DB_ALIAS From c528d92630383ff849f5f8b5bcf199d3721dc677 Mon Sep 17 00:00:00 2001 From: Anubhav Date: Thu, 25 Jul 2019 20:47:35 +0530 Subject: [PATCH 3/4] Added args and kwargs support to decorator for using master or slave database --- django_replicated/decorators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_replicated/decorators.py b/django_replicated/decorators.py index 82c2b5b..9d26b44 100644 --- a/django_replicated/decorators.py +++ b/django_replicated/decorators.py @@ -29,10 +29,10 @@ def use_state_in_function(forced_state='master'): def _make_decorator(func): - def wrapper(): + def wrapper(*args, **kwargs): prev_state = routers.state() # Store previous state routers.init(forced_state) # Set state to the forced_state - func() + func(*args, **kwargs) # If previous state was master, set it back # Handling function calls from other functions or classes if prev_state == 'master': From afa5c550ba3cc3ebeb116d7b9c8d2a95990f2396 Mon Sep 17 00:00:00 2001 From: Gurpreet Singh Date: Sun, 2 Feb 2025 22:03:06 +0530 Subject: [PATCH 4/4] changes for python upgrade --- django_replicated/middleware.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/django_replicated/middleware.py b/django_replicated/middleware.py index 6379021..859f52a 100644 --- a/django_replicated/middleware.py +++ b/django_replicated/middleware.py @@ -9,7 +9,8 @@ from django import db from django.conf import settings -from django.utils import six, functional +from django.utils import functional +import six try: # django 1.10+ from django import urls