我有一个包含多个应用程序的项目,每个应用程序都有自己的数据库。我有一个工作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
。
我尝试覆盖此行为失败并使这些函数使用我想要的数据库别名。
你知道有什么办法吗?
答案 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)