我设置了基于URL的数据库路由(受this答案启发),以便将同一应用程序用于不同的项目/数据库。这些项目不需要共享任何数据,访问控制由每个项目自己管理,我需要为每个项目创建一个管理站点。就像在原始帖子中一样,我使用数据库路由器和中间件,该中间件从请求路径确定要使用哪个数据库,例如/test/process/1将被路由到数据库test,并且/default/process/2将被路由到数据库default

import threading
from django.conf import settings

request_cfg = threading.local()

class RouterMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        path = request.path.lstrip('/').split('/')
        if path[0] in settings.DATABASES:
            request_cfg.db = path[0]

    def process_response(self, request, response):
        if hasattr(request_cfg, 'db'):
            del request_cfg.db
        return response

class DatabaseRouter(object):
    def _default_db(self):
        if hasattr(request_cfg, 'db') and request_cfg.db in settings.DATABASES:
            return request_cfg.db
        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()

然后需要扩展url模式,以包括引用特定数据库的子路径。我是通过这样在项目级别urls.py中对URL进行硬编码来做到这一点的:
urlpatterns = [
  url(r'^default/admin/', include(admin.site.urls)),  # does not work
  url(r'^test/admin/', include(admin.site.urls)),  # does not work
  url(r'^default/', include('logbook.urls', namespace='anything')),
  url(r'^test/', include('logbook.urls', namespace='anything else'))]

我承认这不是很好,但是我期望不必管理多个数据库。有趣的是,命名空间参数是什么都没有关系,但必须给出它。该应用程序的原始 namespace 为logbook,用于在应用程序的所有 View 和模板上进行url反转。

然后,在应用程序级别urls.py中,必须定义app_name(并等于原始 namespace ):
app_name = 'logbook'

urlpatterns = [
    url(r'^$', views.redirect_index, name='index'),
    url(r'^(?P<date>[0-9]{4}[0-9]{2})/$', views.Index.as_view(), name='index'),
.....

在 View 中,我按照django文档中的说明向每个current_app=request.resolver_match.namespace调用添加了一个reverse() kwarg。模板中的URL解析不需要任何修改。

总体而言,这很好,但有两个异常(exception):

任意管理 View 的
  • url反转都将始终解析为urls.py中的第一个条目
  • 我无法使其主要与django.contrib.auth.middleware.AuthenticationMiddleware一起使用,我认为是因为LOGINLOGIN_REDIRECT是常量。

  • 我想知道这是否是一种干净的方法,是否可以解决上述两个异常(exception)。如果没有,什么是更好的解决方案?

    最佳答案

    这是您正在寻找的文章。

    Django Multi DB Documentation

    它说明了如何设置多个数据库,以及与之一起使用的管理控制台。如它所说,您需要为第二个数据库(不是默认数据库)创建一个自定义模型,并使用文档中提供的方法进行注册。

    关于python - 基于URL的数据库路由,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43189830/

    10-12 21:56
    查看更多