首页 > 解决方案 > 按主机名路由数据库

问题描述

我想将主机上的特定请求路由到不同的数据库,例如,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

标签: pythondjango

解决方案


在您的查询集上指定您的数据库怎么样,我认为这样做会更容易。

#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()

不要忘记修改你的settings.py:

#settings.py

DATABASE_ROUTERS = ['path.to.DatabaseRouter']

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

推荐阅读