gpt4 book ai didi

database - 为什么已知有效的 Django 模型实例在从数据库检索后会失败 is_valid()?

转载 作者:搜寻专家 更新时间:2023-10-30 20:13:24 25 4
gpt4 key购买 nike

我们有一个 Django 模型 ToolDataset 和一个 ModelForm ToolForm。在模型中,每个实例或数据库行都称为数据集,主键称为 dataset_id。第一次通过时,用户填写未绑定(bind)的表单并提交。从概念上讲,这是用于验证、保存和分析数据集的 View 代码:

if (request.method == 'POST') and (not dataset_id):
form = ToolForm(request.POST)
if form.is_valid():
new_dataset = form.save()
dataset_id = new_dataset.pk
results = analyze(form.cleaned_data)
else:
<validation error code>

我认为到目前为止这是非常正常的。请注意,除非数据有效,否则不会保存表单数据并且不会分配 dataset_id。

现在一段时间过去了,用户想要返回到这个特定的旧数据集,也许是为了更改数据并重新分析它。因此,无论采用何种方式,都会组成一个类似于 www.finesite.com/Tool/X/的 URL,其中 X 是对应于用户想要使用的特定数据行的 dataset_id。通过 URLconf,调用 View 代码的不同分支,我们认为它应该如下所示:

if (request.method != 'POST') and (dataset_id):
oldset = get_object_or_404(ToolDataset, pk=dataset_id)
form = ToolForm(instance=oldset)
if form.is_valid():
results = analyze(form.cleaned_data)
else:
<validation error code that we expected would never run>

好吧,事实证明,这个数据集在我们存储时是有效的,现在却无法验证,这令人惊讶。我们使用 manage.py shell 稍微检查一下表单。以下是我们发现的一些内容:

>>> form.is_valid()
False
>>> form.errors
{}
>>> form.non_field_errors()
[]
>>> form.is_bound
False

运行 form.as_p() 会生成一个完整的表单。

一位非常能干的同事在 django/forms/models.py 中发现了一个未记录的 API 函数,称为 model_to_dict()。他建议用这个代替,

form = BXEEP_L_Form(model_to_dict(oldset), instance=oldset),

为此,

form = BXEEP_L_Form(instance=oldset).

它现在可以工作了——根据 shell,表单是有效的和绑定(bind)的——但我充满了疑问。为什么这行得通?为什么这是必要的?有没有更标准的方法来做到这一点?对于一个看起来如此普通和简单的用例,必须使用未记录的内部函数似乎很奇怪。

最佳答案

form.is_valid() 验证 form.data 字典,它是通过 Form(data=request.POST) 的构造函数发送的>

ModelForm.instance 将数据与特定表行相关联,因此保存必须执行更新而不是插入。这也通过构造函数传递。

然而,这两者是相互独立的。如果您想使用旧实例的数据创建表单,您应该执行以下操作:

ToolForm(data=oldinstance.__data__, instance=oldinstance)

但是,您可能真的不想立即绑定(bind)数据。

ToolForm(instance=oldinstance)

仅当 ToolForm 实例 is_changed()

呈现在 html 中并更新记录时,从实例中填充正确的值

关于database - 为什么已知有效的 Django 模型实例在从数据库检索后会失败 is_valid()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2377306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com