2014-10-27 9 views
2

У меня есть проект с несколькими приложениями, каждый из которых имеет свою собственную базу данных. У меня есть рабочий routers.py, чтобы указать правильную базу данных для каждой модели. В одном из приложений используется дочерний узел django-admin для управления его моделями.Сайт администратора использует базу данных по умолчанию в Django 1.6

Это все работает отлично в Django 1.5, но при переходе на Django 1.6, я больше не в состоянии изменить свои модели: Когда я получить доступ к edit странице модели, я получаю сообщение об ошибке «[SQL Server Native Client 11.0]Login timeout expired».

После некоторого расследования кажется, что Django пытается подключиться к базе данных default, которая содержит только фиктивные данные в этом проекте, так как ее нельзя использовать нигде.

Почему Django пытается подключиться к базе данных default в 1.6, тогда как она работает нормально в 1.5? Как я могу исправить эту проблему в 1.6?

[EDIT]

После еще некоторых исследований я обнаружил, что Django использует декоратор @transaction.atomic несколько функций своего класса ModelAdmin.

Глядя на код этого декоратора, похоже, он предназначен для поддержки возможности указать алиас базы данных, которую необходимо использовать для этой атомной сделки с @transaction.atomic(using), а в противном случае, если только что звонил с @transaction.atomic, как это в классе ModelAdmin Django он будет использовать DEFAULT_DB_ALIAS, определенный в django.db.utils.

Я пробовал безуспешно, чтобы переопределить это поведение и заставить эти функции использовать псевдоним базы данных, который я хочу.

Вы знаете какой-либо способ сделать это?

+0

Рассмотрит прошу на [ИРЦ #django] (https://code.djangoproject.com/wiki/IrcFAQ) – aliteralmind

+0

https: //docs.djangoproject. ком/ен/DEV/темы/дб/мульти-дб/# обнажая-м интерфейс ultiple-databases-in-django-s-admin Администратор Django не имеет явной поддержки для нескольких баз данных. Если вы хотите предоставить интерфейс администратора для модели в базе данных, отличной от той, которая задана вашей маршрутизаторной цепочкой, вам нужно написать собственные классы ModelAdmin, которые будут направлять администратору использование конкретной базы данных для контента. – StefanNch

+0

@StefanNch: Маршрутизатора базы данных достаточно, и я использую его. [Django сообщает об этом] (https://docs.djangoproject.com/en/1.6/topics/db/multi-db/#exposing-multiple-databases-in-django-s-admin-interface): «Если вы хотите предоставить интерфейс администратора для модели в базе данных, отличной от той, которая указана вашей цепью маршрутизатора ... » – hynekcer

ответ

0

Я, наконец, нашел способ заставить администратора Django использовать базу данных, которую я хочу, но это действительно взломано. Если кто-то приходит с лучшим решением, пожалуйста, опубликуйте его.

Я создал файл с именем admin_helper.py, где я переопределить методы, которые используют @transaction.atomic декоратора в Django кодовую, с точно таким же содержанием, и с помощью декоратора @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) 
Смежные вопросы