У меня есть пользовательский Django 1.11 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
Его заявленная цель - создать экземпляр из очищенных данных формы.Однако эта строка вызывает у меня проблемы:
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 не содержат названия поля.Поскольку у меня есть более сложный набор входных данных на стороне формы HTML, это имя поля фактически не существует в нем.Таким образом, хотя поле существует в cleaned_data
, оно никогда не будет обновлено.Простой обходной путь - добавить скрытый ввод с правильным именем в форму, но это кажется излишне хакерским.
Мне интересно: каково обоснование проверки данных POST на этом этапе?Проблема в том, как я динамически создаю сложные поля в интерфейсе?