Instance construction fails on form data check

安稳与你 提交于 2019-12-13 03:46:49

问题


I have a custom Django 1.11 Widget that allows for a dynamic number of key/value pairs to be entered into a form, which are assembled into a dict by the widget's value_from_datadict method. When I check the form's cleaned_data, I see exactly what I'm expecting:

{'fieldname': {'key1': 'value1', ....}

However, when the form is saved, fieldname isn't being updated. I've traced this down to the implementation of 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

Its stated purpose is to create an instance from the cleaned data of a form. However, this line causes problems for me:

    if (f.has_default() and
            form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))):
        continue

It skips fields if the POST data doesn't contain the name of the field. Because I have a more complex set of inputs on HTML side of the form, that field name doesn't actually exist in it. So even though the field exists in cleaned_data, it will never be updated. The simple workaround is to add a hidden input with the correct name on the form, but this seems unnecessarily hacky.

I'm curious: what is the rationale for checking against the POST data at this point? Is the issue how I'm dynamically constructing complex fields in the front end?

来源:https://stackoverflow.com/questions/54661557/instance-construction-fails-on-form-data-check

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!