2013-07-22 26 views
1

嗨,ModelForms和多Datasbase - 在form.is_valid錯誤()

我只是有多個數據庫在我的Django的網站..每個用戶使用不同的數據庫,在用戶配置設置好的。

我的問題是:

我怎樣才能設置爲使用特定的數據庫中的ModelForm?

我得到這些錯誤:表XX不存在。因爲django是嘗試使用我的身份驗證數據庫..我嘗試使用路由器,但我在互聯網上找到的所有示例都不使用UserProfile中的數據庫名稱。

這裏是我的表:

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

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

這裏我回溯:

Environment: 


Request Method: POST 
Request URL: http://127.0.0.1:8000/cadastro/pessoa/novo/ 

Django Version: 1.5.1 
Python Version: 2.7.2 
Installed Applications: 
('django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'django.contrib.admin', 
'django_evolution', 
'debug_toolbar', 
'pagination', 
'bootstrap_toolkit', 
'web_core') 
Installed Middleware: 
('django.middleware.common.CommonMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware', 
'debug_toolbar.middleware.DebugToolbarMiddleware', 
'pagination.middleware.PaginationMiddleware') 


Traceback: 
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response 
    115.       response = callback(request, *callback_args, **callback_kwargs) 
File "/Users/fellipeh/PycharmProjects/webconflex/cadastros/views.py" in EditaPessoa 
    47.    if formPessoa.is_valid(): 
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in is_valid 
    126.   return self.is_bound and not bool(self.errors) 
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in _get_errors 
    117.    self.full_clean() 
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in full_clean 
    274.   self._post_clean() 
File "/Library/Python/2.7/site-packages/django/forms/models.py" in _post_clean 
    344.    self.validate_unique() 
File "/Library/Python/2.7/site-packages/django/forms/models.py" in validate_unique 
    353.    self.instance.validate_unique(exclude=exclude) 
File "/Library/Python/2.7/site-packages/django/db/models/base.py" in validate_unique 
    731.   errors = self._perform_unique_checks(unique_checks) 
File "/Library/Python/2.7/site-packages/django/db/models/base.py" in _perform_unique_checks 
    826.    if qs.exists(): 
File "/Library/Python/2.7/site-packages/django/db/models/query.py" in exists 
    596.    return self.query.has_results(using=self.db) 
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py" in has_results 
    442.   return bool(compiler.execute_sql(SINGLE)) 
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql 
    840.   cursor.execute(sql, params) 
File "/Library/Python/2.7/site-packages/django/db/backends/util.py" in execute 
    41.    return self.cursor.execute(sql, params) 
File "/Library/Python/2.7/site-packages/firebird/base.py" in execute 
    158.    six.reraise(utils.DatabaseError, utils.DatabaseError(*self.error_info(e, query, params)), sys.exc_info()[2]) 
File "/Library/Python/2.7/site-packages/firebird/base.py" in execute 
    150.    return self.cursor.execute(q, params) 
File "/Library/Python/2.7/site-packages/fdb/fbcore.py" in execute 
    3322.          PreparedStatement(operation, self, True)) 
File "/Library/Python/2.7/site-packages/fdb/fbcore.py" in __init__ 
    1934.     "Error while preparing SQL statement:") 

Exception Type: DatabaseError at /cadastro/pessoa/novo/ 
Exception Value: ('Error while preparing SQL statement:\n- SQLCODE: -204\n- Dynamic SQL Error\n- SQL error code = -204\n- Table unknown\n- PESSOA\n- At line 1, column 41', u'-204 -- SELECT FIRST 1 (1) AS "A" FROM "PESSOA" WHERE "PESSOA"."IDPESSOA" = -1') 

這裏是我的佩索阿型號:

class Pessoa(models.Model): 
    idsys_point_cliente = models.CharField(max_length=28, primary_key=True) 
    idpessoa = models.IntegerField(verbose_name=u'Código', primary_key=True, default=-1) 
    data_cadastro = models.DateTimeField(u'Data/Hora Cadastro', default=datetime.now, blank=True, editable=False) 
    data_atualizacao = models.DateTimeField(verbose_name=u'Data/Hora da Última Atualização', default=datetime.now, 
             blank=True) 
    status = models.CharField(verbose_name=u'Status', 
          max_length=1, 
          default='A', 
          choices=Ativo_Inativo_CHOICE) 
    razao_social = models.CharField(u'Razão Social *', max_length=70, null=False) 
    nome_fantasia = models.CharField(u'Nome Fantasia', max_length=70, blank=True, null=True) 
    endereco = models.CharField(u'Endereço *', max_length=150, null=False) 
    numero = models.CharField(u'Número *', max_length=30, null=False) 
    bairro = models.CharField(u'Bairro *', max_length=40, null=False) 
    complemento = models.CharField(u'Complemento', max_length=30, blank=True, null=True) 
    idcidade = models.ForeignKey('web_core.Cidade', verbose_name="Cidade *", 
          db_column='idcidade', null=False, blank=False) 
    email = models.EmailField(u'E-Mail', max_length=100, blank=True, null=True) 
    fisico_juridico = models.CharField('Tipo Cadastro *', 
            max_length=1, 
            default='F', 
            choices=FIS_JUR_CHOICE) 
    fis_cpf = models.CharField(u'CPF', max_length=14, null=True, blank=True) 
    jur_cnpj = models.CharField(u'CNPJ', max_length=18, null=True, blank=True) 
    telefone1 = models.CharField(u'Telefone', max_length=14) 
    idrepresentante = models.IntegerField(u'Representante', null=True, blank=True, editable=False) 

    class Meta: 
     ordering = ['razao_social'] 
     managed = False 
     db_table = 'pessoa' 

    def __unicode__(self): 
     return self.razao_social 
+0

關鍵是使用自定義auth後端,它將接收用戶數據並決定使用哪個數據庫。你可以在這裏找到示例:https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#writing-an-authentication-backend –

+0

你可以發送示例嗎?我如何使用自定義身份驗證後端來設置is_valid? –

+0

哦,抱歉誤會。身份驗證後端是用戶身份驗證。如果您使用身份驗證,那麼這是下一步。可能您需要在自定義用戶模型中描述驗證過程。 –

回答

1

回覆我的問題......

獲得此權利的唯一方法t是使一箇中間件獲取數據庫名稱和與當地人合作,是這樣的:

文件: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路由器:

文件:AU throuter:

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 

注:我需要把進口在每個閃避,因爲Django的1.5.1有一個bug,如果你把導入文件..循環進口的首要..

後這一點,再次改變你的settings.py添加路由器:

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

記住

我這樣做,因爲我有一個數據庫,僅用於身份驗證..每個用戶都可以訪問不同的數據庫,具體取決於保存在dbname字段中的內容。

如果您有其他解決方案,請讓我知道!

感謝大家。