表单数据检查中的实例构建失败

时间:2019-02-13 02:27:05

标签: django django-forms django-widget

我有一个自定义的Django 1.11 {{ botany }},它允许将动态数量的键/值对输入表单,并由小部件的Widget组合成dict方法。当我检查表单的value_from_datadict时,我确切地看到了我所期望的:

cleaned_data

但是,保存表单后,{'fieldname': {'key1': 'value1', ....} 不会被更新。我将其追溯到fieldname的实现中:

django.forms.models.construct_instance

其声明的目的是从表单的清除数据中创建一个实例。但是,此行为我带来了问题:

def construct_instance(form, instance, fields=None, exclude=None):
    """
    Constructs and returns a model instance from the bound ``form``'s
    ``cleaned_data``, but does not save the returned instance to the
    database.
    """
    from django.db import models
    opts = instance._meta

    cleaned_data = form.cleaned_data
    file_field_list = []
    for f in opts.fields:
        if not f.editable or isinstance(f, models.AutoField) \
                or f.name not in cleaned_data:
            continue
        if fields is not None and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        # Leave defaults for fields that aren't in POST data, except for
        # checkbox inputs because they don't appear in POST data if not checked.
        if (f.has_default() and
                form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))):
            continue
        # Defer saving file-type fields until after the other fields, so a
        # callable upload_to can use the values from other fields.
        if isinstance(f, models.FileField):
            file_field_list.append(f)
        else:
            f.save_form_data(instance, cleaned_data[f.name])

    for f in file_field_list:
        f.save_form_data(instance, cleaned_data[f.name])

    return instance

如果POST数据不包含字段名称,则会跳过字段。因为我在表单的HTML端具有一组更复杂的输入,所以该字段名称实际上并不存在。因此,即使该字段存在于 if (f.has_default() and form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))): continue 中,也永远不会更新。一种简单的解决方法是在表单上添加具有正确名称的隐藏输入,但这似乎不必要。

我很好奇:此时检查POST数据的理由是什么?这是我如何在前端动态构造复杂字段的问题吗?

0 个答案:

没有答案