1

我有这个 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 router,因为“特定”数据库是在我的用户配置文件中设置的,而且我不知道如何在 db-router 类中获取 UserProfile ..

我知道我可以在 ClienteForm.save(using=XXX) 中使用,但是当我尝试 ClienteForm.is_valid 时出现错误,因为 django 尝试使用“默认”数据库。

谢谢

4

1 回答 1

1

回答我自己的问题...

做到这一点的唯一方法是制作一个中间件来获取数据库名称并与本地人一起使用,如下所示:

文件:中间件.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:

文件:作者:

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 有一个错误,如果您将 import 放入文件顶部.. 循环导入..

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

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

记住

我这样做是因为我有一个数据库,仅用于身份验证.. 每个用户都可以访问不同的数据库,具体取决于 dbname 字段中保存的内容。

如果您有其他解决方案,请告诉我!

谢谢大家。

于 2013-08-02T15:56:02.487 回答