如何强制ModelForm使用特定的数据库?

时间:2013-07-23 14:08:29

标签: django-forms

我有这个ModelForm:

class ClienteForm(ModelForm):
   class Meta:
     model = Pessoa

   def __init__(self, *args, **kwargs):
     vUserProfile = kwargs.pop('vUserProfile', None)
     super(ClienteForm, self).__init__(*args, **kwargs)

如何强制使用特定数据库?

我不能使用db路由器,因为"具体"数据库正在我的用户配置文件中设置,我不知道如何在db-router类中获取UserProfile ..

我知道我可以在ClienteForm.save中使用(使用= XXX),但是当我尝试ClienteForm.is_valid时我得到了错误,因为django试图使用"默认"数据库中。

感谢

1 个答案:

答案 0 :(得分:1)

回复我自己的问题......

实现这一目标的唯一方法是让一个中间件获取数据库名称并与本地人合作,如下所示:

文件:middleware.py

from threading import local
from django.contrib.sessions.models import Session
from django.contrib.auth.models import User
from web_core.models import UserProfile

my_local_global = local()


class CustomerMiddleware(object):
    def process_request(self, request):
        my_local_global.database_name = get_database_name(request)


def get_database_name(request):
    session_key = request.session.session_key
    try:
        session = Session.objects.get(session_key=session_key)
        uid = session.get_decoded().get('_auth_user_id')
        user = User.objects.get(pk=uid)

        profile = UserProfile.objects.get(pk=uid)

        if profile:
            return profile.dbname
        else:
            return None
    except:
        return None

在此之后,在 settings.py 中添加 middleware.py

MIDDLEWARE_CLASSES = (
(..)
    'middleware.CustomerMiddleware',
)

完成后再制作一个文件来获取db router:

文件:authrouter:

class PadraoRouter(object):
    def db_for_read(self, model, **hints):
        from middleware import my_local_global
        return my_local_global.database_name

    def db_for_write(self, model, **hints):
        from middleware import my_local_global
        return my_local_global.database_name

    def allow_relation(self, obj1, obj2, **hints):
        return None

    def allow_syncdb(self, db, model):
        return True


class AuthRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'auth':
            return 'auth_db'
        if model._meta.app_label == 'sessions':
            return 'auth_db'
        if model._meta.app_label == 'web_core':
            return 'auth_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'auth':
            return 'auth_db'
        if model._meta.app_label == 'sessions':
            return 'auth_db'
        if model._meta.app_label == 'web_core':
            return 'auth_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'auth' or\
           obj2._meta.app_label == 'auth':
            return True
        if obj1._meta.app_label == 'sessions' or\
           obj2._meta.app_label == 'sessions':
            return True
        if obj1._meta.app_label == 'web_core' or\
           obj2._meta.app_label == 'web_core':
            return True
        return None

    def allow_syncdb(self, db, model):
        if db == 'auth_db':
            return model._meta.app_label == 'auth'
        elif model._meta.app_label == 'auth':
            return False
        return None

注意:我需要在每个def中加上 import ,因为Django 1.5.1有一个bug,如果你把import放到文件的顶部..循环导入..

之后,再次更改 settings.py 以添加路由器:

DATABASE_ROUTERS = ['authrouter.AuthRouter',
                    'authrouter.PadraoRouter']

<强>记住

我这样做,因为我有一个数据库,只有auth ..每个用户都可以访问不同的数据库,具体取决于dbname字段中的保存。

如果您有其他解决方案,请让我知道!

感谢大家。