管理站点在Django 1.6中使用默认数据库

时间:2014-10-27 01:04:12

标签: python django admin

我有一个包含多个应用程序的项目,每个应用程序都有自己的数据库。我有一个工作routers.py来指定每个模型使用的正确数据库。其中一个应用使用django-admin子网站来管理其模型。

这在Django 1.5中运行良好,但是当转移到Django 1.6时,我不再能够编辑我的模型:当我访问模型的edit页面时,我收到错误“{ {1}}”。

经过一番调查后,似乎Django尝试连接到数据库[SQL Server Native Client 11.0]Login timeout expired,该数据库只包含此项目中的虚拟数据,因为它不应该在任何地方使用。

为什么Django尝试连接到1.6中的default数据库,而它在1.5中运行良好?我怎样才能在1.6中解决这个问题?

[编辑]

经过一些研究,我发现Django将装饰器default用于其类@transaction.atomic的一些函数。

查看这个装饰器的代码,似乎它的目的是支持使用ModelAdmin指定需要用于此原子事务的数据库别名的可能性,否则,如果只调用{与@transaction.atomic(using) Django类中的{1}}一样,它将使用@transaction.atomic中定义的ModelAdmin

我尝试覆盖此行为失败并使这些函数使用我想要的数据库别名。

你知道有什么办法吗?

1 个答案:

答案 0 :(得分:0)

我终于找到了一种方法来强制Django管理员使用我想要的数据库,但它真的很hacky。如果有人提供更好的解决方案,请发布。

我创建了一个名为admin_helper.py的文件,我重新定义了在Django代码库中使用@transaction.atomic装饰器的方法,内容完全相同,并使用装饰器@transaction.atomic(DATABASE_ALIAS)告诉Django使用正确的数据库:

DATABASE_ALIAS = 'alias_of_the_database_i_want_to_use'

class ModelAdminCustom(admin.ModelAdmin):
    @csrf_protect_m
    @transaction.atomic(DATABASE_ALIAS)
    def add_view(self, request, form_url='', extra_context=None):
        # exact same content as the method defined in django.contrib.admin.options.ModelAdmin

    @csrf_protect_m
    @transaction.atomic(DATABASE_ALIAS)
    def change_view(self, request, object_id, form_url='', extra_context=None):
        # exact same content as the method defined in django.contrib.admin.options.ModelAdmin

    @csrf_protect_m
    @transaction.atomic(DATABASE_ALIAS)
    def delete_view(self, request, object_id, extra_context=None):
        # exact same content as the method defined in django.contrib.admin.options.ModelAdmin

class MultiDBUserAdmin(UserAdmin):
    @sensitive_post_parameters_m
    @csrf_protect_m
    @transaction.atomic(DATABASE_ALIAS)
    def add_view(self, request, form_url='', extra_context=None):
        # exact same content as the method defined in django.contrib.auth.admin.UserAdmin

# Unregister existing instance of UserAdmin for the User model, and register my own
try:
    admin.site.unregister(User)
finally:
    admin.site.register(User, MultiDBUserAdmin)

然后在我的正常admin.py:

from myapp.admin_helper import ModelAdminCustom

class MyModelAdmin(ModelAdminCustom):
    pass

admin.site.register(MyModel, MyModelAdmin)