【发布时间】:2011-01-23 13:17:48
【问题描述】:
我们有一个 Django 模型 ToolDataset 和一个 ModelForm ToolForm。在模型中,每个实例或数据库行都称为数据集,主键称为 dataset_id。第一次通过时,用户填写一个未绑定的表单并提交。从概念上讲,这是用于验证、保存和分析数据集的视图代码:
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,视图代码的不同分支被调用,我们认为应该如下所示:
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 中发现了一个名为 model_to_dict() 的未记录 API 函数。他建议用这个代替,
form = BXEEP_L_Form(model_to_dict(oldset), instance=oldset),
为此,
form = BXEEP_L_Form(instance=oldset).
它现在可以工作了——根据 shell,表单是有效且绑定的——但我充满了疑问。为什么这行得通?为什么这是必要的?有没有更标准的方法来做到这一点?对于一个看起来如此普通和简单的用例,不得不使用一个未记录的内部函数似乎很奇怪。
【问题讨论】:
标签: database django validation forms