Django, базы данных и декораторы имеет решение, использующее django DATABASE_ROUTERS .
Здесь вы можете найти пример из docs.djangoproject.com .Ниже приводится краткое изложение «Джанго, базы данных и декораторы»:
1.Написание пользовательского декоратора
Здесь назовите decorator
как decorators.py
:
from functools import wraps
try:
from threading import local
except ImportError:
from _threading_local import local
threadlocal = local()
class use_db_for_reads(object):
def __init__(self, database_name):
self.database_name = database_name
def __enter__(self):
setattr(threadlocal, 'DB_FOR_READ_ONLY', self.database_name)
def __exit__(self, exc_type, exc_value, traceback):
setattr(threadlocal, 'DB_FOR_READ_ONLY', None)
def __call__(self, test_func):
@wraps(test_func)
def inner(*args, **kwargs):
return test_func(*args, **kwargs)
return inner
def get_thread_local(attr, default=None):
return getattr(threadlocal, attr, default)
class AnalyticsRouter(object):
def db_for_read(self, model, **hints):
return get_thread_local('DB_FOR_READ_ONLY', 'default')
def db_for_write(self, model, **hints):
return 'default'
def allow_relation(self, obj1, obj2, **hints):
return True
2.обновить настройки
Вот пример DATABASES
в settings.py
:
DATABASES = {
'default': {
...
},
'read-only': {
...
}
}
DATABASE_ROUTERS = ['decorators.AnalyticsRouter']
3.Вот как это использовать
from decorators import use_db_for_reads
# Here call method() using DATABASE_A
with use_db_for_reads(DATABASE_A):
method()
# here call method() using DATABASE_B
with use_db_for_reads(DATABASE_B):
method()