按主机名进行数据库路由

时间:2019-04-11 10:55:39

标签: python django

我想将主机上的特定请求路由到其他数据库,例如,如果我要使用其他数据库,则www.example.com上的默认应用程序正在www.sub.example.com上运行。我可以通过request.META['HOST']来获取主机名,并且尝试了类似的方法

class MultipleDatabaseRequestRouterMiddleware (object):

    def process_view( self, request, view_func, args, kwargs ):
        request.META['HOST']

    def process_response( self, request, response ):
        return response


class DatabaseRouter(object):
    def db_for_read(self, model, **hints):
        return None

    def db_for_write(self, model, **hints):
        return None

我的问题是我的DatabaseRouter在这里不知道请求,如何将请求传递到DatabaseRouter

1 个答案:

答案 0 :(得分:2)

如何在查询集上指定数据库,我认为这样做会更容易。

#settings.py
DATABASES = {
'default': {
    'ENGINE': 'django.contrib.gis.db.backends.postgis',
    'NAME': 'write_db',
    'USER': 'postgres',
    'PASSWORD': '',
    'HOST': 'localhost',
    'PORT': '5432',
    },
'another_db': {
    'ENGINE': 'django.contrib.gis.db.backends.postgis',
    'NAME': 'read_db',
    'USER': 'postgres',
    'PASSWORD': '',
    'HOST': 'localhost',
    'PORT': '5432',
}}

# views.py
def some_views(request):
    if request.META["HOST"] == "www.example.com":
        queryset = YourModels.objects.using("default").all()
    elif request.META["HOST"] == "www.sub.example.com":
        queryset = YourModels.objects.using("another_db").all()

    return

更新

希望它对您有帮助。 :)

import threading 
from  django.utils.deprecation import MiddlewareMixin

request_cfg = threading.local()


class RouterMiddleware(MiddlewareMixin):
    def process_request(self, request):
        url_host = request.META.get("HTTP_HOST")
        if url_host == "www.example.com":
            request_cfg.cfg = "read_db"
        elif url_host == "www.sub.example.com":
            request_cfg.cfg = "default"
        return None

    def process_response(self, request, response ):
        return response


class DatabaseRouter:
    def _default_db(self):
        if hasattr( request_cfg, 'cfg' ):
            return request_cfg.cfg
        else:
            return 'default'

    def db_for_read(self, model, **hints):
        return self._default_db()


    def db_for_write(self, model, **hints):
        return self._default_db()

不要忘记修改您的设置。py:

#settings.py

DATABASE_ROUTERS = ['path.to.DatabaseRouter']

MIDDLEWARE = [...,
              path.to.RouterMiddleware]