Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django模型表单在特定数据库中是_valid()_Python_Django_Django Models_Django Forms - Fatal编程技术网

Python Django模型表单在特定数据库中是_valid()

Python Django模型表单在特定数据库中是_valid(),python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我在我的设置.py中定义了两个不同的数据库连接(“default”和“banco1”) 然后在某个视图中,我收到一篇帖子,其中包含一些我想根据我创建的ModelForm验证的数据: product_form = ProductForm(request.POST) if product_form.is_valid(): 产品型号: class Product(models.Model): name = models.CharField(max_length=125, blank=F

我在我的
设置.py
中定义了两个不同的数据库连接(“default”和“banco1”)

然后在某个视图中,我收到一篇帖子,其中包含一些我想根据我创建的
ModelForm
验证的数据:

 product_form = ProductForm(request.POST)
 if product_form.is_valid():
产品型号:

class Product(models.Model):

    name = models.CharField(max_length=125, blank=False, null=False)
    description = models.CharField(max_length=255, blank=True)
    abbreviation = models.CharField(max_length=15, blank=True)
    category = models.ForeignKey('inventory.Category',
        on_delete=models.SET_NULL, null=True, blank=True)
    metric = models.CharField(max_length=15, blank=True, null=True)
表格:

class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'description', 'abbreviation', 'category', 'metric']
观点:

 def create(request):
        if request.method != 'POST':
            return JsonResponse('Operação inválida', safe=False)

        product_form = ProductForm(request.POST)
        if product_form.is_valid():
            f = product_form.save(commit = False)
            f.save(using=request.session['database'])
            return HttpResponse("Novo product salvo com sucesso")
        else:
            return HttpResponse("Impossível salvar product. Verifique os campos")
产品模型始终保存在“banco1”数据库中,因此应该从“banco1”数据库查询FK验证,但每当我尝试使用
产品表单进行验证时,FK验证是否有效()
Django尝试查询“默认”数据库,并抛出验证错误,因为“默认”数据库中无法满足FK约束

如何设置一个模型表单,使其对手动选择的数据库进行验证

编辑

建议我使用DB路由器模式,以便能够选择正确的数据库配置,这很好。我的问题是,这种选择应该基于一些标准,而不仅仅是模型。如何将一些变量从视图传递到db router类中的
db\u for\u read
方法

EDIT2

新ProductForm类

class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'description', 'abbreviation', 'category', 'metric']

    def __init__(self,database):
        category = forms.ModelChoiceField(queryset=Category.objects.using(database).all())
尝试在我的视图中实例化表单,如下所示:

product_form = ProductForm(request.POST, request.session['database'])
这给了我一个错误:

init()接受2个位置参数,但给出了3个

我知道以我的方式重写
\uuu init\uuu
方法是无效的,但我要用python来实现这一点

编辑3

最后错误:

回溯:

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\core\handlers\base.py” 在得到答复时 149response=self.process\u异常\u由\u中间件(e,请求)

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\core\handlers\base.py” 在得到答复时 147响应=包装的回调(请求,*回调参数,**回调参数)

文件“C:\Users\Pavarine\Documents\Visual Studio 创建中的“2015\Projects\gims\gims\gims\apps\inventory\views.py” 247如果产品形式有效():

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\forms\forms.py” 这是有效的吗 161返回self.is_绑定而不是self.errors

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\forms\forms.py” 出错 153self.full_clean()

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\forms\forms.py” 干干净净 362self._clean_fields()

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\forms\forms.py” 在干净的田地里 374value=field.widget.value\u from_datadict(self.data,self.files, self.add_前缀(名称))

文件“C:\Users\Pavarine\Documents\Visual Studio 2015\Projects\gims\gims\env\lib\site packages\django\forms\widgets.py” 来自数据目录的输入值 231返回数据。获取(名称)

异常类型:AttributeError at/inventory/product/create异常 值:“tuple”对象没有属性“get”


要启用路由器,只需将其添加到
设置.py中的
数据库\u路由器
,请参阅此处的详细信息:

每个路由器方法都会得到
提示
字典,字典中应该包含表示所用模型实例的
实例
键。根据您希望从视图中获得的信息,您可能会很好地使用实例属性中的信息。请参见此处:

即:

除此之外,我认为没有其他直接的方法将信息从活动视图传递到路由器,因为路由器应该与模型一起工作,并根据使用的模型做出决策

DB路由器用于模型层中的自动DB选择,但模型方法允许手动选择DB。请参见此处的示例:

因此,另一种解决方案是重新定义表单类的方法,即
save()
(请参阅),并使用
参数手动保存表单数据,指定要与
一起使用的DB。即:

class ProductForm(ModelForm):
    class Meta:
        ...

    def save(self, commit=True):
        product_to_save=super(ProductForm, self).save(commit=False)
        #the above creates product_to_save instance, but doesn't saves it to DB
        product_to_save.save(using=='banco1')
        return product_to_save
在我的评论中,我建议对需要根据其他DB验证的字段进行子类化,但可能还有更简单的方法。。。由于它是FK字段,所以可能是
modelcooicefield
的实例,它接受构造函数中的
queryset
参数,因此您可以提供它,即:

class ProductForm(ModelForm):
   category_field = forms.ModelMultipleChoiceField(queryset=Category.objects.using('banco1'))
    ...
见:

对编辑的回答2

您重新定义构造函数的方式您的
数据库
参数得到
request.POST
request.session['database']
没有映射到任何东西,这就是您得到错误的原因

您应该考虑其他参数,并调用超类构造函数,否则会破坏MRO,因此类似这样的操作应该可以完成这项工作:

class ProductForm(ModelForm):
    ...

    def __init__(self, *args, db_to_use='default', **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        #category = forms.ModelChoiceField(queryset=Category.objects.using(db_to_use).all())
        #the below line suggested as improvement by Alasdair and confirmed as working by Pavarine, so I updated the answer here
        self.fields['category'].queryset = Category.objects.using(database).all()
然后像往常一样,使用命名参数:

product_form = ProductForm(request.POST, db_to_use=request.session['database'])

您是否有设置告诉它使用
banco1
作为
db\u for_read
作为
Product
型号的
db\u?@mragh我可以这样做,但现在我想到了另一个相关问题。我将编辑我的问题。请显示完整的表单和视图。@Alasdair我已更新了问题。我已在@Nikita的答案中添加了一条注释,因为它与我将要建议的内容非常相似。我非常感谢您的帮助。可以在db_for_read方法中读取会话数据(以前保存在视图中)?会话数据是视图层中活动的
请求的一部分,db路由器在模型层上工作。我不知道有什么直接的方法可以做到这一点,可能是通过破解Djnago内部并使用内部方法实现的
product_form = ProductForm(request.POST, db_to_use=request.session['database'])