ModelForms和Multiple Datasbase - form.is_valid()中的错误 [英] ModelForms and Multiple Datasbase - error in form.is_valid()
问题描述
我的django网站中只有多个数据库。每个用户使用不同的数据库,设置在UserProfile中。
我的问题是:
如何将modelForm设置为使用特定的数据库?
我收到这些错误:表XX不存在。因为django尝试使用我的auth db ..我尝试使用路由器,但是我在互联网上发现的所有示例,不使用UserProfile中的数据库名称。
这里是我的表单:
class ClienteForm(ModelForm):
class Meta:
model = Pessoa
def __init __(self,* args,** kwargs):
vUserProfile = kwargs.pop('vUserProfile',None)
super(ClienteForm,自我).__ init __(* args,** kwargs)
这里我的追溯:
环境:
请求方法:POST
请求URL :http://127.0.0.1:8000/cadastro/pessoa/novo/
Django版本:1.5.1
Python版本:2.7.2
安装的应用程序:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.mes s $'
'django.contrib.staticfiles',
'django.contrib.admin',
'django_evolution',
'debug_toolbar',
'pagination'
'bootstrap_toolkit'
'web_core')
安装的中间件:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions。中间件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')
追溯:
文件/Library/Python/2.7/site-packages/django/core/handlers/base.pyin get_response
115. response = callback(request,* callback_args,** callback_kwargs )
文件/ Users / dropsipeh / PycharmProjec如果formPessoa.is_valid():
文件/Library/Python/2.7/site-packages/django/forms/forms.py,则在EditaPessoa
中的ts / webconflex / cadastros / views.py in is_valid
126. return self.is_bound而不是bool(self.errors)
文件/Library/Python/2.7/site-packages/django/forms/forms.py在_get_errors
117. self.full_clean()
文件/Library/Python/2.7/site-packages/django/forms/forms.py在full_clean
274. self._post_clean()
文件/Library/Python/2.7/site-packages/django/forms/models.py在_post_clean
344. self.validate_unique()
文件/Library/Python/2.7/site-packages /django/forms/models.pyin validate_unique
353. self.instance.validate_unique(exclude = exclude)
文件/Library/Python/2.7/site-packages/django/db/models/ base.pyin validate_unique
731. errors = self._perform_unique_checks(unique_checks)
文件/Library/Python/2.7/site-packages/django/db/mo _perform_unique_checks中的dels / base.py
826.如果qs.exists():
文件/Library/Python/2.7/site-packages/django/db/models/query.py存在
596. return self.query.has_results(using = self.db)
文件/Library/Python/2.7/site-packages/django/db/models/sql/query.pyin has_results
442. return bool(compiler.execute_sql(SINGLE))
文件/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py在execute_sql
840. cursor.execute(sql,params)
执行
中的文件/Library/Python/2.7/site-packages/django/db/backends/util.py41. return self.cursor .execute(sql,params)
文件/Library/Python/2.7/site-packages/firebird/base.py执行
158. six.reraise(utils.DatabaseError,utils.DatabaseError( * self.error_info(e,query,params)),sys.exc_info()[2])
文件/Library/Python/2.7/site-packages/firebird/base.py中执行
150. return self.cursor.exe可执行文件(q,params)
执行
中的文件/Library/Python/2.7/site-packages/fdb/fbcore.py3322. PreparedStatement(operation,self,True))
文件/Library/Python/2.7/site-packages/fdb/fbcore.pyin __init__
1934.准备SQL语句时出错:)
异常类型:DatabaseError at / cadastro / pessoa / novo /
异常值:('准备SQL语句时出错:\\\
- SQLCODE:-204\\\
-动态SQL错误\-- SQL错误代码= -204\\\
-表未知\-- PESSOA\\\
-在第1行列41',u'-204 - SELECT FIRST 1(1)ASAFROMPESSOAwherePESSOAIDPESSOA= -1 ')
这是我的Pessoa模型:
< pre class =lang-python prettyprint-override>
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ÚltimaAtualizaçã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ãoSocial *',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:
= ['razao_social ]
managed = False
db_table ='pessoa'
def __unicode __(self):
return self.razao_social
回复我自己的问题...
获取此权限的唯一方法是使一个中间件获取数据库名称并与本地用户一起工作,如下所示:
文件:middleware.py
$ b $从django.contrib.sessions.models导入会话从django.contrib.auth.models导入的
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
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)
如果个人资料:
返回profile.dbname
其他:
返回无
除外:
返回无
之后,在 settings.py 中添加 middleware.py :
MIDDLEWARE_CLASSES =(
(..)
'middleware.CustomerMiddleware',
)
完成,再一个文件获取db路由器:
文件:authrouter:
class PadraoRouter(object):
def db_for_read(self,model, **提示):
从中间件导入my_local_global
返回my_local_global.database_name
def db_for_write(self,model,** hints):
from middleware import my_local_global
返回my_local_global.database_name
def allow_relation(self,obj1,obj2,** hints):
return无
def allow_syncdb(self,db,model)
return True
class AuthRouter(object):
def db_for_read(self,model,** hints):
如果model._meta.app_label =='auth':
返回'auth_db'
如果model._meta.app_label =='会话':
返回'auth_db'
如果model._meta.app_label == 'web_core':
返回'auth_db'
返回无
def db_for_write(self,model,** hints):
if model._meta.app_label == 'auth':
返回'auth_db'
如果model._meta.app_label =='会话':
返回'auth_db'
如果model._meta.app_label =='web_core ':
return'auth_db'
return None
def allow_relation(self,o bj1,obj2,** hints):
如果obj1._meta.app_label =='auth'或\
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'或者'
obj2._meta.app_label =='web_core':
return True
return None
def allow_syncdb(self,db,model):
如果db =='auth_db':
返回model._meta.app_label =='auth'
elif model._meta.app_label =='auth':
return False
return无
注意:我需要在每个项目中输入 import def,因为Django 1.5.1有一个错误,如果你把导入到文件的顶部..循环导入..
之后,再次更改你的设置.py 广告d路由器:
DATABASE_ROUTERS = ['authrouter.AuthRouter',
'authrouter.PadraoRouter']
记住
这样做,因为我有一个数据库,只能用于auth ..每个用户都可以访问不同的数据库,具体取决于dbname中保存的内容。
解决方案,请让我知道!
感谢大家。
Hi,
I just have multiple database in my django website.. each user use a different database, setted in UserProfile.
My problem is:
How can I set the modelForm to use the specific database?
I got these error: table XX doesn't exists. because django is try to use my auth db.. I try tu use router, but all samples I found in internet, doesn't use database name from UserProfile.
Here is my Form:
class ClienteForm(ModelForm):
class Meta:
model = Pessoa
def __init__(self, *args, **kwargs):
vUserProfile = kwargs.pop('vUserProfile', None)
super(ClienteForm, self).__init__(*args, **kwargs)
Here my traceback:
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')
Here is my Pessoa model:
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
Reply my own question...
The only way to get this right is make one middleware to get database name and work with locals, like this:
File: 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
after this, add middleware.py in your settings.py:
MIDDLEWARE_CLASSES = (
(..)
'middleware.CustomerMiddleware',
)
to finish, make one more file to get db router:
File: 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
NOTE: I need to put import in each def, because Django 1.5.1 has a bug, if you put import into top of file.. cycle imports..
after this, change again your settings.py to add the router:
DATABASE_ROUTERS = ['authrouter.AuthRouter',
'authrouter.PadraoRouter']
Remember
I make this way, because I have one database, only for auth.. each user can access a different database, depending what is save in dbname field.
If you have other solution, please let's me know!
Thanks to everybody.
这篇关于ModelForms和Multiple Datasbase - form.is_valid()中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!